Merged 'master'
Conflicts: magit.el
This commit is contained in:
parent
cb49072477
commit
67288d178b
13 changed files with 1290 additions and 575 deletions
|
@ -1,17 +1,18 @@
|
|||
lispdir = $(datadir)/emacs/site-lisp
|
||||
sitestartdir = @SITESTART@
|
||||
|
||||
lisp_DATA = magit.el magit.elc
|
||||
lisp_DATA = magit.el magit.elc magit-svn.el magit-svn.elc magit-topgit.el magit-topgit.elc
|
||||
sitestart_DATA = 50magit.el
|
||||
|
||||
info_TEXINFOS = magit.texi
|
||||
|
||||
CLEANFILES = magit.elc
|
||||
EXTRA_DIST = magit.el 50magit.el magit.spec
|
||||
CLEANFILES = magit-*.elc
|
||||
EXTRA_DIST = magit.el 50magit.el magit.spec magit-svn.el magit-topgit.el
|
||||
|
||||
%.elc: %.el
|
||||
@if [ $(builddir) != $(srcdir) ]; then ln $(srcdir)/$*.el .; fi
|
||||
emacs --batch --eval '(byte-compile-file "$*.el")'
|
||||
emacs --batch --eval "(add-to-list 'load-path \"$(srcdir)\")" \
|
||||
--eval '(byte-compile-file "$*.el")'
|
||||
@if [ $(builddir) != $(srcdir) ]; then rm -f $*.el; fi
|
||||
|
||||
|
||||
|
|
65
README.md
65
README.md
|
@ -1,56 +1,67 @@
|
|||
It's Magit! A Emacs mode for Git.
|
||||
==================================
|
||||
|
||||
[github pages](http://philjackson.github.com/magit)
|
||||
Magit is an interface to Git for Emacs. Unlike Emacs's native
|
||||
[version control support][vc], Magit can take advantage of Git's
|
||||
native features without breaking compatibility with other systems.
|
||||
|
||||
I started to write Magit to learn about Git and to figure out how I
|
||||
would be using Git in a 'natural' way. Magit will grow and hopefully
|
||||
become more coherent as I learn more about Git and good ways to use
|
||||
it. Feedback is welcome!
|
||||
|
||||
Magit is owned by Marius Vollmer and is currently maintained by Phil
|
||||
Jackson. For a full list of contributors have a look at magit.el.
|
||||
To get started see the [Magit User Manual][manual] or perhaps the
|
||||
[cheatsheet][cheatsheet] if you're in a hurry. There's also an
|
||||
excellent [Magit screencast][screencast] by Alex Vollmer which
|
||||
demonstrates some of the major features.
|
||||
|
||||
Installing
|
||||
----------
|
||||
|
||||
Download the latest tarball from
|
||||
[the github download page](http://github.com/philjackson/magit/downloads).
|
||||
Download the latest tarball from [the github download page][download],
|
||||
then Magit can be installed with the popular recipe of:
|
||||
|
||||
And then Magit can be installed with the popular recipe of:
|
||||
./autogen.sh # If you got the sources directly from Git
|
||||
./configure
|
||||
make install
|
||||
|
||||
$ ./autogen.sh # If you got the sources directly from Git
|
||||
$ ./configure
|
||||
$ make install
|
||||
|
||||
This will put magit.el into /usr/local/share/emacs/site-lisp, where
|
||||
This will put magit.el into `/usr/local/share/emacs/site-lisp`, where
|
||||
Emacs should be able to find it. Then add
|
||||
|
||||
(require 'magit)
|
||||
|
||||
to your .emacs file.
|
||||
to your `.emacs` file.
|
||||
|
||||
Getting started
|
||||
---------------
|
||||
|
||||
To get started with Magit, open any file in a Git repository in Emacs
|
||||
and run 'M-x magit-status'. Read the online help of magit-mode ('C-h
|
||||
m' in the Magit buffer), make some changes to your files, and try to
|
||||
and run `M-x magit-status`. Read the short help for magit-mode (`C-h
|
||||
m` in the Magit buffer), make some changes to your files, and try to
|
||||
commit them.
|
||||
|
||||
Learning more
|
||||
-------------
|
||||
|
||||
The Magit User Manual describes things with more words than the online
|
||||
help. You can read it in Emacs with 'C-u C-h i magit.info' for
|
||||
example, or on the web at
|
||||
The [Magit User Manual][manual] describes things with more words than
|
||||
the online help. You can read it in Emacs with `C-u C-h i
|
||||
magit.info`, or [on the web][manual].
|
||||
|
||||
[the manual](http://philjackson.github.com/magit/magit.html)
|
||||
If you have any questions, please use [the mailing list][google group]
|
||||
at Google Groups.
|
||||
|
||||
If you have questions, please use the mailing list at
|
||||
Magit's website is currently hosted [on GitHub][website].
|
||||
|
||||
[google group](http://groups.google.com/group/magit/)
|
||||
Development
|
||||
-----------
|
||||
|
||||
Magit's web home is currently at
|
||||
Magit was started by Marius Vollmer and is currently maintained by
|
||||
Phil Jackson. For a full list of contributors have a look at
|
||||
`magit.el` in the source distribution.
|
||||
|
||||
[github pages](http://philjackson.github.com/magit)
|
||||
Magit's canonical source repository is currently
|
||||
[hosted on GitHub][development].
|
||||
|
||||
[vc]: http://www.gnu.org/software/emacs/manual/html_node/emacs/Version-Control.html#Version-Control
|
||||
[website]: http://philjackson.github.com/magit
|
||||
[development]: http://github.com/philjackson/magit
|
||||
[manual]: http://philjackson.github.com/magit/magit.html
|
||||
[cheatsheet]: http://daemianmack.com/magit-cheatsheet.html
|
||||
[screencast]: http://vimeo.com/2871241
|
||||
[download]: http://github.com/philjackson/magit/downloads
|
||||
[google group]: http://groups.google.com/group/magit/
|
||||
|
|
6
bin/authors.pl
Executable file
6
bin/authors.pl
Executable file
|
@ -0,0 +1,6 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
# :-)
|
||||
|
||||
/(\d{4}).*?_(.+)/&&\$a{$2}->{$1}for`git log --pretty=format:%aD_%an`;
|
||||
print"Copyright (C) ".join(", ",sort keys %{$a{$_}})." $_.\n"for sort keys %a
|
54
bin/mk_rel.bash
Executable file
54
bin/mk_rel.bash
Executable file
|
@ -0,0 +1,54 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
function configure_ac_ver_ok {
|
||||
cat configure.ac | grep "${1}" || return 1
|
||||
}
|
||||
|
||||
function magit_el_ver_ok {
|
||||
grep -e ";; Version: *$1" magit.el || return 1
|
||||
}
|
||||
|
||||
USAGE="usage: ${0##*/} <tag>"
|
||||
|
||||
tag="${1}"
|
||||
|
||||
[ ${#} -lt 1 ] && {
|
||||
echo ${USAGE} >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
# does the specified tag exist?
|
||||
if ! git tag | grep "${tag}"; then
|
||||
echo "Make sure you've tagged '${tag}'"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
# grab that tag
|
||||
git co "${tag}"
|
||||
|
||||
# correct version in magit?
|
||||
if ! magit_el_ver_ok "$tag"; then
|
||||
echo "Please set version in magit.el to $tag"
|
||||
git co master
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# correct version in configure.ac?
|
||||
if ! configure_ac_ver_ok "$tag"; then
|
||||
echo "Please set AC_INIT to $tag in configure.ac"
|
||||
git co master
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# clean up if we need to
|
||||
[ -f Makefile ] && make distclean
|
||||
|
||||
./autogen.sh
|
||||
|
||||
./configure
|
||||
|
||||
make dist
|
||||
|
||||
git co master
|
|
@ -1,4 +1,4 @@
|
|||
AC_INIT(magit, 0.8)
|
||||
AC_INIT(magit, 0.8.2)
|
||||
AC_CONFIG_SRCDIR([magit.el])
|
||||
AM_INIT_AUTOMAKE([1.10])
|
||||
|
||||
|
|
183
magit-svn.el
Normal file
183
magit-svn.el
Normal file
|
@ -0,0 +1,183 @@
|
|||
;;; magit-svn.el --- git-svn plug-in for Magit
|
||||
|
||||
;; Copyright (C) 2008, 2009 Marius Vollmer
|
||||
;; Copyright (C) 2008 Linh Dang
|
||||
;; Copyright (C) 2008 Alex Ott
|
||||
;; Copyright (C) 2008 Marcin Bachry
|
||||
;; Copyright (C) 2009 Alexey Voinov
|
||||
;; Copyright (C) 2009 John Wiegley
|
||||
;; Copyright (C) 2010 Yann Hodique
|
||||
;;
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This plug-in provides git-svn functionality as a separate component of Magit
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'magit)
|
||||
|
||||
;; git svn commands
|
||||
|
||||
(defun magit-svn-find-rev (rev &optional branch)
|
||||
(interactive
|
||||
(list (read-string "SVN revision: ")
|
||||
(if current-prefix-arg
|
||||
(read-string "In branch: "))))
|
||||
(let* ((sha (apply 'magit-git-string
|
||||
`("svn"
|
||||
"find-rev"
|
||||
,(concat "r" rev)
|
||||
,@(when branch (list branch))))))
|
||||
(if sha
|
||||
(magit-show-commit
|
||||
(magit-with-section sha 'commit
|
||||
(magit-set-section-info sha)
|
||||
sha))
|
||||
(error "Revision %s could not be mapped to a commit" rev))))
|
||||
|
||||
(defun magit-svn-rebase ()
|
||||
(interactive)
|
||||
(magit-run-git-async "svn" "rebase"))
|
||||
|
||||
(defun magit-svn-dcommit ()
|
||||
(interactive)
|
||||
(magit-run-git-async "svn" "dcommit"))
|
||||
|
||||
(defun magit-svn-enabled ()
|
||||
(not (null (magit-svn-get-ref-info))))
|
||||
|
||||
(defun magit-svn-get-local-ref (url)
|
||||
(let ((branches (cons (magit-get "svn-remote" "svn" "fetch")
|
||||
(magit-get-all "svn-remote" "svn" "branches")))
|
||||
(base-url (magit-get "svn-remote" "svn" "url"))
|
||||
(result nil))
|
||||
(while branches
|
||||
(let* ((pats (split-string (pop branches) ":"))
|
||||
(src (replace-regexp-in-string "\\*" "\\\\(.*\\\\)" (car pats)))
|
||||
(dst (replace-regexp-in-string "\\*" "\\\\1" (cadr pats)))
|
||||
(base-url (replace-regexp-in-string "\\+" "\\\\+" base-url))
|
||||
(pat1 (concat "^" src "$"))
|
||||
(pat2 (cond ((equal src "") (concat "^" base-url "$"))
|
||||
(t (concat "^" base-url "/" src "$")))))
|
||||
(cond ((string-match pat1 url)
|
||||
(setq result (replace-match dst nil nil url))
|
||||
(setq branches nil))
|
||||
((string-match pat2 url)
|
||||
(setq result (replace-match dst nil nil url))
|
||||
(setq branches nil)))))
|
||||
result))
|
||||
|
||||
(defvar magit-svn-get-ref-info-cache nil
|
||||
"A cache for svn-ref-info.
|
||||
As `magit-get-svn-ref-info' might be considered a quite
|
||||
expensive operation a cache is taken so that `magit-status'
|
||||
doesn't repeatedly call it.")
|
||||
|
||||
(defun magit-svn-get-ref-info (&optional use-cache)
|
||||
"Gather details about the current git-svn repository.
|
||||
Return nil if there isn't one. Keys of the alist are ref-path,
|
||||
trunk-ref-name and local-ref-name.
|
||||
If USE-CACHE is non-nil then return the value of `magit-get-svn-ref-info-cache'."
|
||||
(if (and use-cache magit-svn-get-ref-info-cache)
|
||||
magit-svn-get-ref-info-cache
|
||||
(let* ((fetch (magit-get "svn-remote" "svn" "fetch"))
|
||||
(url)
|
||||
(revision))
|
||||
(when fetch
|
||||
(let* ((ref (cadr (split-string fetch ":")))
|
||||
(ref-path (file-name-directory ref))
|
||||
(trunk-ref-name (file-name-nondirectory ref)))
|
||||
(set (make-local-variable
|
||||
'magit-svn-get-ref-info-cache)
|
||||
(list
|
||||
(cons 'ref-path ref-path)
|
||||
(cons 'trunk-ref-name trunk-ref-name)
|
||||
;; get the local ref from the log. This is actually
|
||||
;; the way that git-svn does it.
|
||||
(cons 'local-ref
|
||||
(with-temp-buffer
|
||||
(insert (or (magit-git-string "log" "--first-parent")
|
||||
""))
|
||||
(goto-char (point-min))
|
||||
(cond ((re-search-forward "git-svn-id: \\(.+/.+?\\)@\\([0-9]+\\)" nil t)
|
||||
(setq url (match-string 1)
|
||||
revision (match-string 2))
|
||||
(magit-svn-get-local-ref url))
|
||||
(t
|
||||
(setq url (magit-get "svn-remote" "svn" "url"))
|
||||
nil))))
|
||||
(cons 'revision revision)
|
||||
(cons 'url url))))))))
|
||||
|
||||
(defun magit-svn-get-ref (&optional use-cache)
|
||||
"Get the best guess remote ref for the current git-svn based branch.
|
||||
If USE-CACHE is non nil, use the cached information."
|
||||
(let ((info (magit-svn-get-ref-info use-cache)))
|
||||
(cdr (assoc 'local-ref info))))
|
||||
|
||||
(magit-define-inserter svn-unpulled (&optional use-cache)
|
||||
(when (magit-svn-get-ref-info t)
|
||||
(magit-git-section 'svn-unpulled
|
||||
"Unpulled commits (SVN):" 'magit-wash-log
|
||||
"log" "--pretty=format:* %H %s"
|
||||
(format "HEAD..%s" (magit-svn-get-ref use-cache)))))
|
||||
|
||||
(magit-define-inserter svn-unpushed (&optional use-cache)
|
||||
(when (magit-svn-get-ref-info t)
|
||||
(magit-git-section 'svn-unpushed
|
||||
"Unpushed commits (SVN):" 'magit-wash-log
|
||||
"log" "--pretty=format:* %H %s"
|
||||
(format "%s..HEAD" (magit-svn-get-ref use-cache)))))
|
||||
|
||||
(magit-define-section-jumper svn-unpushed "Unpushed commits (SVN)")
|
||||
|
||||
(defun magit-svn-remote-string ()
|
||||
(let ((svn-info (magit-svn-get-ref-info)))
|
||||
(when svn-info
|
||||
(concat (cdr (assoc 'url svn-info))
|
||||
" @ "
|
||||
(cdr (assoc 'revision svn-info))))))
|
||||
|
||||
(defun magit-svn-remote-update ()
|
||||
(interactive)
|
||||
(when (magit-svn-enabled)
|
||||
(magit-run-git-async "svn" "fetch")))
|
||||
|
||||
(define-prefix-command 'magit-svn-prefix 'magit-svn-map)
|
||||
(define-key magit-svn-map (kbd "r") 'magit-svn-rebase)
|
||||
(define-key magit-svn-map (kbd "c") 'magit-svn-dcommit)
|
||||
(define-key magit-svn-map (kbd "f") 'magit-svn-remote-update)
|
||||
(define-key magit-svn-map (kbd "s") 'magit-svn-find-rev)
|
||||
(define-key magit-mode-map (kbd "N") 'magit-svn-prefix)
|
||||
|
||||
(easy-menu-define magit-svn-extension-menu
|
||||
nil
|
||||
"Git SVN extension menu"
|
||||
'("Git SVN"
|
||||
["Rebase" magit-svn-rebase (magit-svn-enabled)]
|
||||
["Fetch" magit-svn-remote-update (magit-svn-enabled)]
|
||||
["Commit" magit-svn-dcommit (magit-svn-enabled)]))
|
||||
(easy-menu-add-item 'magit-mode-menu '("Extensions") magit-svn-extension-menu)
|
||||
|
||||
(add-hook 'magit-after-insert-unpulled-commits-hook
|
||||
(lambda () (magit-insert-svn-unpulled t)))
|
||||
(add-hook 'magit-after-insert-unpushed-commits-hook
|
||||
(lambda () (magit-insert-svn-unpushed t)))
|
||||
|
||||
(add-hook 'magit-remote-string-hook 'magit-svn-remote-string)
|
||||
|
||||
(provide 'magit-svn)
|
||||
;;; magit-svn.el ends here
|
91
magit-topgit.el
Normal file
91
magit-topgit.el
Normal file
|
@ -0,0 +1,91 @@
|
|||
;;; magit-topgit.el --- topgit plug-in for Magit
|
||||
|
||||
;; Copyright (C) 2008, 2009 Marius Vollmer
|
||||
;; Copyright (C) 2008 Linh Dang
|
||||
;; Copyright (C) 2008 Alex Ott
|
||||
;; Copyright (C) 2008 Marcin Bachry
|
||||
;; Copyright (C) 2009 Alexey Voinov
|
||||
;; Copyright (C) 2009 John Wiegley
|
||||
;; Copyright (C) 2010 Yann Hodique
|
||||
;;
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This plug-in provides topgit functionality as a separate component of Magit
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'magit)
|
||||
|
||||
(defcustom magit-topgit-executable "tg"
|
||||
"The name of the TopGit executable."
|
||||
:group 'magit
|
||||
:type 'string)
|
||||
|
||||
;;; Topic branches (using topgit)
|
||||
|
||||
(defun magit-topgit-create-branch (branch parent)
|
||||
(when (zerop (or (string-match "t/" branch) -1))
|
||||
(magit-run* (list magit-topgit-executable "create"
|
||||
branch (magit-rev-to-git parent))
|
||||
nil nil nil t)
|
||||
t))
|
||||
|
||||
(defun magit-topgit-pull ()
|
||||
(when (file-exists-p ".topdeps")
|
||||
(magit-run* (list magit-topgit-executable "update")
|
||||
nil nil nil t)
|
||||
t))
|
||||
|
||||
(defun magit-topgit-wash-topic ()
|
||||
(if (search-forward-regexp "^..\\(t/\\S-+\\)\\s-+\\(\\S-+\\)\\s-+\\(\\S-+\\)"
|
||||
(line-end-position) t)
|
||||
(let ((topic (match-string 1)))
|
||||
(delete-region (match-beginning 2) (match-end 2))
|
||||
(goto-char (line-beginning-position))
|
||||
(delete-char 4)
|
||||
(insert "\t")
|
||||
(goto-char (line-beginning-position))
|
||||
(magit-with-section topic 'topic
|
||||
(magit-set-section-info topic)
|
||||
(forward-line)))
|
||||
(delete-region (line-beginning-position) (1+ (line-end-position))))
|
||||
t)
|
||||
|
||||
(defun magit-topgit-wash-topics ()
|
||||
(let ((magit-old-top-section nil))
|
||||
(magit-wash-sequence #'magit-topgit-wash-topic)))
|
||||
|
||||
(magit-define-inserter topics ()
|
||||
(magit-git-section 'topics
|
||||
"Topics:" 'magit-topgit-wash-topics
|
||||
"branch" "-v"))
|
||||
|
||||
(magit-add-action (item info "discard")
|
||||
((topic)
|
||||
(when (yes-or-no-p "Discard topic? ")
|
||||
(magit-run* (list magit-topgit-executable "delete" "-f" info)
|
||||
nil nil nil t))))
|
||||
|
||||
(magit-add-action (item info "visit")
|
||||
((topic)
|
||||
(magit-checkout info)))
|
||||
|
||||
(add-hook 'magit-after-insert-stashes 'magit-insert-topics)
|
||||
(add-hook 'magit-create-branch-command-hook 'magit-topgit-create-branch)
|
||||
(add-hook 'magit-pull-command-hook 'magit-topgit-pull)
|
||||
|
||||
(provide 'magit-topgit)
|
||||
;;; magit-topgit.el ends here
|
38
magit.texi
38
magit.texi
|
@ -49,6 +49,7 @@ as an extension to Emacs.
|
|||
* Rewriting::
|
||||
* Pushing and Pulling::
|
||||
* Interfacing with Subversion::
|
||||
* Using Git Directly::
|
||||
@end menu
|
||||
|
||||
@node Introduction
|
||||
|
@ -302,6 +303,10 @@ Typing @kbd{C-c C-s} will toggle the @code{--signoff} option. The
|
|||
default is determined by the @code{magit-commit-signoff} customization
|
||||
variable.
|
||||
|
||||
Typing @kbd{C-c C-e} will toggle the @code{--allow-empty} option. This
|
||||
allows you to make commits that serve as notes, without including any
|
||||
changes.
|
||||
|
||||
If you change your mind and don't want to go ahead with your commit
|
||||
while you are in the @code{*magit-log-edit*} buffer, you can just
|
||||
switch to another buffer, continue editing there, staging and
|
||||
|
@ -499,7 +504,8 @@ local branch. Deleting works for both local and remote branches.
|
|||
You can merge the branch in the current line by typing @kbd{m} for a
|
||||
manual merge and @kbd{M} for an automatic merge.
|
||||
|
||||
With @kbd{b} you can check out the branch in the current line.
|
||||
With @kbd{RET} or @kbd{b} you can check out the branch in the current
|
||||
line.
|
||||
|
||||
Typing @kbd{$} shows the @code{*magit-process*} buffer which contains
|
||||
the transcript of the most recent command.
|
||||
|
@ -648,13 +654,17 @@ it, like from any other diff.
|
|||
|
||||
Magit will run @code{git push} when you type @kbd{P}. If you give a
|
||||
prefix argument to @kbd{P}, you will be prompted for the repository to
|
||||
push to. When no default remote repositor has been configured yet for
|
||||
push to. When no default remote repository has been configured yet for
|
||||
the current branch, you will be prompted as well. Typing @kbd{P} will
|
||||
only push the current branch to the remote. In other words, it will
|
||||
run @code{git push <remote> <branch>}.
|
||||
only push the current branch to the remote. In other words, it will run
|
||||
@code{git push <remote> <branch>}. The branch will be created in the
|
||||
remote if it doesn't exist already. The local branch will be configured
|
||||
so that it pulls from the new remote branch.
|
||||
|
||||
Typing @kbd{f} will run @code{git remote update} and @kbd{F} will run
|
||||
@code{git pull}. When you don't have a default branch configured to
|
||||
Typing @kbd{f} will run @code{git remote update}. With a prefix arg,
|
||||
it will prompt for the name of the remote to update. Typing @kbd{F}
|
||||
will run @code{git pull} (with a prefix arg will pull with
|
||||
@code{--rebase}). When you don't have a default branch configured to
|
||||
be pulled into the current one, you will be asked for it.
|
||||
|
||||
If there is a default remote repository for the current branch, Magit
|
||||
|
@ -674,13 +684,21 @@ Magit shows them in a section called @emph{Unpulled changes}. Typing
|
|||
@node Interfacing with Subversion
|
||||
@chapter Interfacing with Subversion
|
||||
|
||||
Typing @kbd{N r} runs @code{git svn rebase} and typing @kbd{N c} runs
|
||||
@code{git svn dcommit}.
|
||||
Typing @kbd{N r} runs @code{git svn rebase}, typing @kbd{N c} runs
|
||||
@code{git svn dcommit} and typing @kbd{N f} runs @code{git svn fetch}.
|
||||
|
||||
@kbd{N f} will prompt you for a (numeric, Subversion) revision and
|
||||
@kbd{N s} will prompt you for a (numeric, Subversion) revision and
|
||||
then search for a corresponding Git sha1 for the commit. This is
|
||||
limited to the path of the remote Subversion repository. With a prefix
|
||||
(@kbd{C-u N f} the user will also be prompted for a branch to search
|
||||
(@kbd{C-u N s} the user will also be prompted for a branch to search
|
||||
in.
|
||||
|
||||
@node Using Git Directly
|
||||
@chapter Using Git Directly
|
||||
|
||||
For situations when Magit doesn't do everything you need, you can run
|
||||
raw Git commands using @kbd{:}. This will prompt for a Git command, run
|
||||
it, and refresh the status buffer. The output can be viewed by typing
|
||||
@kbd{$}.
|
||||
|
||||
@bye
|
||||
|
|
32
mk_rel.bash
32
mk_rel.bash
|
@ -1,32 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
USAGE="usage: ${0##*/} <tag>"
|
||||
|
||||
tag="${1}"
|
||||
|
||||
[ ${#} -lt 1 ] && {
|
||||
echo ${USAGE} >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
# does the specified tag exist?
|
||||
if ! git tag | grep "${tag}"; then
|
||||
echo "Make sure you've tagged '${tag}'"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
# grab that tag
|
||||
git co "${tag}"
|
||||
|
||||
# clean up if we need to
|
||||
[ -f Makefile ] && make distclean
|
||||
|
||||
./autogen.sh
|
||||
|
||||
./configure
|
||||
|
||||
make dist
|
||||
|
||||
git co master
|
172
rebase-mode.el
Normal file
172
rebase-mode.el
Normal file
|
@ -0,0 +1,172 @@
|
|||
;;; rebase-mode -- edit git rebase files.
|
||||
|
||||
;; Copyright (C) 2010 Phil Jackson
|
||||
;;
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Allows the editing of a git rebase file (which you might get when
|
||||
;; using 'git rebase -i' or hitting 'E' in Magit). Assumes editing is
|
||||
;; happening in a server.
|
||||
|
||||
(defvar rebase-mode-action-line-re
|
||||
(rx
|
||||
line-start
|
||||
(group
|
||||
(|
|
||||
(any "presf")
|
||||
"pick"
|
||||
"reword"
|
||||
"edit"
|
||||
"squash"
|
||||
"fixup"))
|
||||
(char space)
|
||||
(group
|
||||
(** 7 40 (char "0-9" "a-f" "A-F"))) ;sha1
|
||||
(char space)
|
||||
(* not-newline))
|
||||
"Regexp that matches an action line in a rebase buffer.")
|
||||
|
||||
(defvar rebase-mode-font-lock-keywords
|
||||
(list
|
||||
(list rebase-mode-action-line-re
|
||||
'(1 font-lock-keyword-face)
|
||||
'(2 font-lock-builtin-face))
|
||||
(list (rx line-start (char "#") (* not-newline)) 0 font-lock-comment-face))
|
||||
"Font lock keywords for rebase-mode.")
|
||||
|
||||
(defvar key-to-action-map
|
||||
'(("c" . "pick")
|
||||
("r" . "reword")
|
||||
("e" . "edit")
|
||||
("s" . "squash")
|
||||
("f" . "fixup"))
|
||||
"Mapping from key to action.")
|
||||
|
||||
(defvar rebase-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map (kbd "q") 'server-edit)
|
||||
(define-key map (kbd "C-c C-c") 'server-edit)
|
||||
|
||||
(define-key map (kbd "a") 'rebase-mode-abort)
|
||||
(define-key map (kbd "C-c C-k") 'rebase-mode-abort)
|
||||
|
||||
(define-key map (kbd "M-p") 'rebase-mode-move-line-up)
|
||||
(define-key map (kbd "M-n") 'rebase-mode-move-line-down)
|
||||
(define-key map (kbd "k") 'rebase-mode-kill-line)
|
||||
|
||||
(define-key map (kbd "n") 'next-line)
|
||||
(define-key map (kbd "p") 'previous-line)
|
||||
|
||||
map)
|
||||
"Keymap for rebase-mode. Note this will be added to by the
|
||||
top-level code which defines the edit functions.")
|
||||
|
||||
;; create the functions which edit the action lines themselves (based
|
||||
;; on `key-to-action-map' above)
|
||||
(mapc (lambda (key-action)
|
||||
(let ((fun-name (intern (concat "rebase-mode-" (cdr key-action)))))
|
||||
;; define the function
|
||||
(eval `(defun ,fun-name ()
|
||||
(interactive)
|
||||
(rebase-mode-edit-line ,(cdr key-action))))
|
||||
|
||||
;; bind the function in `rebase-mode-map'
|
||||
(define-key rebase-mode-map (car key-action) fun-name)))
|
||||
key-to-action-map)
|
||||
|
||||
(defun rebase-mode-edit-line (change-to)
|
||||
"Change the keyword at the start of the current action line to
|
||||
that of CHANGE-TO."
|
||||
(when (rebase-mode-looking-at-action)
|
||||
(let ((buffer-read-only nil)
|
||||
(start (point)))
|
||||
(goto-char (point-at-bol))
|
||||
(kill-region (point) (progn (forward-word 1) (point)))
|
||||
(insert change-to)
|
||||
(goto-char start))))
|
||||
|
||||
(defun rebase-mode-looking-at-action ()
|
||||
"Returns non-nil if looking at an action line."
|
||||
(save-excursion
|
||||
(goto-char (point-at-bol))
|
||||
(looking-at rebase-mode-action-line-re)))
|
||||
|
||||
(defun rebase-mode-move-line-up ()
|
||||
"Move the current action line up."
|
||||
(interactive)
|
||||
(when (rebase-mode-looking-at-action)
|
||||
(let ((buffer-read-only nil)
|
||||
(col (current-column)))
|
||||
(transpose-lines 1)
|
||||
(previous-line 2)
|
||||
(move-to-column col))))
|
||||
|
||||
(defun rebase-mode-move-line-down ()
|
||||
"Assuming the next line is also an action line, move the
|
||||
current line down."
|
||||
(interactive)
|
||||
;; if we're on an action and the next line is also an action
|
||||
(when (and (rebase-mode-looking-at-action)
|
||||
(save-excursion
|
||||
(forward-line)
|
||||
(rebase-mode-looking-at-action)))
|
||||
(let ((buffer-read-only nil)
|
||||
(col (current-column)))
|
||||
(next-line 1)
|
||||
(transpose-lines 1)
|
||||
(previous-line 1)
|
||||
(move-to-column col))))
|
||||
|
||||
(defun rebase-mode-abort ()
|
||||
"Abort this rebase (by emptying the buffer, saving and closing
|
||||
server connection)."
|
||||
(interactive)
|
||||
(when (or (not (buffer-modified-p))
|
||||
(y-or-n-p "Abort this rebase? "))
|
||||
(let ((buffer-read-only nil))
|
||||
(delete-region (point-min) (point-max))
|
||||
(save-buffer)
|
||||
(server-edit))))
|
||||
|
||||
(defun rebase-mode-kill-line ()
|
||||
"Kill the current action line."
|
||||
(interactive)
|
||||
(when (rebase-mode-looking-at-action)
|
||||
(let* ((buffer-read-only nil)
|
||||
(region (list (point-at-bol)
|
||||
(progn (forward-line)
|
||||
(point-at-bol))))
|
||||
;; might be handy to let the user know what went
|
||||
;; somehow... sometime
|
||||
(text (apply 'buffer-substring region)))
|
||||
(apply 'kill-region region))))
|
||||
|
||||
(defun rebase-mode ()
|
||||
(interactive)
|
||||
(kill-all-local-variables)
|
||||
|
||||
(make-local-variable 'font-lock-defaults)
|
||||
(setq font-lock-defaults
|
||||
'(rebase-mode-font-lock-keywords t t nil nil))
|
||||
|
||||
(use-local-map rebase-mode-map)
|
||||
(setq buffer-read-only t)
|
||||
(setq mode-name "rebase-mode" major-mode 'rebase-mode))
|
||||
|
||||
(add-to-list 'auto-mode-alist
|
||||
'("git-rebase-todo" . rebase-mode))
|
||||
|
||||
(provide 'rebase-mode)
|
|
@ -1 +0,0 @@
|
|||
Hi Ho.
|
|
@ -1 +0,0 @@
|
|||
Hello!
|
Loading…
Reference in a new issue