Skip to content

Commit

Permalink
Merge branch 'js/rebase'
Browse files Browse the repository at this point in the history
* js/rebase:
  Teach rebase -i about --preserve-merges
  rebase -i: provide reasonable reflog for the rebased branch
  rebase -i: several cleanups
  ignore git-rebase--interactive
  Teach rebase an interactive mode
  Move the pick_author code to git-sh-setup
  • Loading branch information
Junio C Hamano committed Jul 2, 2007
2 parents e1bc8dc + f09c9b8 commit f36db54
Show file tree
Hide file tree
Showing 8 changed files with 746 additions and 33 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ git-push
git-quiltimport
git-read-tree
git-rebase
git-rebase--interactive
git-receive-pack
git-reflog
git-relink
Expand Down
106 changes: 103 additions & 3 deletions Documentation/git-rebase.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ git-rebase - Forward-port local commits to the updated upstream head
SYNOPSIS
--------
[verse]
'git-rebase' [-v] [--merge] [-C<n>] [--onto <newbase>] <upstream> [<branch>]
'git-rebase' [-i | --interactive] [-v | --verbose] [--merge] [-C<n>]
[-p | --preserve-merges] [--onto <newbase>] <upstream> [<branch>]
'git-rebase' --continue | --skip | --abort

DESCRIPTION
Expand Down Expand Up @@ -208,6 +209,14 @@ OPTIONS
context exist they all must match. By default no context is
ever ignored.

-i, \--interactive::
Make a list of the commits which are about to be rebased. Let the
user edit that list before rebasing.

-p, \--preserve-merges::
Instead of ignoring merges, try to recreate them. This option
only works in interactive mode.

include::merge-strategies.txt[]

NOTES
Expand All @@ -226,9 +235,100 @@ pre-rebase hook script for an example.
You must be in the top directory of your project to start (or continue)
a rebase. Upon completion, <branch> will be the current branch.

Author
INTERACTIVE MODE
----------------

Rebasing interactively means that you have a chance to edit the commits
which are rebased. You can reorder the commits, and you can
remove them (weeding out bad or otherwise unwanted patches).

The interactive mode is meant for this type of workflow:

1. have a wonderful idea
2. hack on the code
3. prepare a series for submission
4. submit

where point 2. consists of several instances of

a. regular use
1. finish something worthy of a commit
2. commit
b. independent fixup
1. realize that something does not work
2. fix that
3. commit it

Sometimes the thing fixed in b.2. cannot be amended to the not-quite
perfect commit it fixes, because that commit is buried deeply in a
patch series. That is exactly what interactive rebase is for: use it
after plenty of "a"s and "b"s, by rearranging and editing
commits, and squashing multiple commits into one.

Start it with the last commit you want to retain as-is:

git rebase -i <after-this-commit>

An editor will be fired up with all the commits in your current branch
(ignoring merge commits), which come after the given commit. You can
reorder the commits in this list to your heart's content, and you can
remove them. The list looks more or less like this:

-------------------------------------------
pick deadbee The oneline of this commit
pick fa1afe1 The oneline of the next commit
...
-------------------------------------------

The oneline descriptions are purely for your pleasure; `git-rebase` will
not look at them but at the commit names ("deadbee" and "fa1afe1" in this
example), so do not delete or edit the names.

By replacing the command "pick" with the command "edit", you can tell
`git-rebase` to stop after applying that commit, so that you can edit
the files and/or the commit message, amend the commit, and continue
rebasing.

If you want to fold two or more commits into one, replace the command
"pick" with "squash" for the second and subsequent commit. If the
commits had different authors, it will attribute the squashed commit to
the author of the last commit.

In both cases, or when a "pick" does not succeed (because of merge
errors), the loop will stop to let you fix things, and you can continue
the loop with `git rebase --continue`.

For example, if you want to reorder the last 5 commits, such that what
was HEAD~4 becomes the new HEAD. To achieve that, you would call
`git-rebase` like this:

----------------------
$ git rebase -i HEAD~5
----------------------

And move the first patch to the end of the list.

You might want to preserve merges, if you have a history like this:

------------------
X
\
A---M---B
/
---o---O---P---Q
------------------

Suppose you want to rebase the side branch starting at "A" to "Q". Make
sure that the current HEAD is "B", and call

-----------------------------
$ git rebase -i -p --onto Q O
-----------------------------

Authors
------
Written by Junio C Hamano <junkio@cox.net>
Written by Junio C Hamano <junkio@cox.net> and
Johannes E. Schindelin <johannes.schindelin@gmx.de>

Documentation
--------------
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ SCRIPT_SH = \
git-fetch.sh \
git-ls-remote.sh \
git-merge-one-file.sh git-mergetool.sh git-parse-remote.sh \
git-pull.sh git-rebase.sh \
git-pull.sh git-rebase.sh git-rebase--interactive.sh \
git-repack.sh git-request-pull.sh git-reset.sh \
git-sh-setup.sh \
git-tag.sh git-verify-tag.sh \
Expand Down
30 changes: 2 additions & 28 deletions git-commit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -483,34 +483,8 @@ fi >>"$GIT_DIR"/COMMIT_EDITMSG
# Author
if test '' != "$use_commit"
then
pick_author_script='
/^author /{
s/'\''/'\''\\'\'\''/g
h
s/^author \([^<]*\) <[^>]*> .*$/\1/
s/'\''/'\''\'\'\''/g
s/.*/GIT_AUTHOR_NAME='\''&'\''/p
g
s/^author [^<]* <\([^>]*\)> .*$/\1/
s/'\''/'\''\'\'\''/g
s/.*/GIT_AUTHOR_EMAIL='\''&'\''/p
g
s/^author [^<]* <[^>]*> \(.*\)$/\1/
s/'\''/'\''\'\'\''/g
s/.*/GIT_AUTHOR_DATE='\''&'\''/p
q
}
'
encoding=$(git config i18n.commitencoding || echo UTF-8)
set_author_env=`git show -s --pretty=raw --encoding="$encoding" "$use_commit" |
LANG=C LC_ALL=C sed -ne "$pick_author_script"`
eval "$set_author_env"
export GIT_AUTHOR_NAME
export GIT_AUTHOR_EMAIL
export GIT_AUTHOR_DATE
eval "$(get_author_ident_from_commit "$use_commit")"
export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
fi
if test '' != "$force_author"
then
Expand Down
Loading

0 comments on commit f36db54

Please sign in to comment.