Skip to content

Commit f36db54

Browse files
committed
Merge branch 'js/rebase'
* 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
2 parents e1bc8dc + f09c9b8 commit f36db54

File tree

8 files changed

+746
-33
lines changed

8 files changed

+746
-33
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ git-push
9696
git-quiltimport
9797
git-read-tree
9898
git-rebase
99+
git-rebase--interactive
99100
git-receive-pack
100101
git-reflog
101102
git-relink

Documentation/git-rebase.txt

Lines changed: 103 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ git-rebase - Forward-port local commits to the updated upstream head
88
SYNOPSIS
99
--------
1010
[verse]
11-
'git-rebase' [-v] [--merge] [-C<n>] [--onto <newbase>] <upstream> [<branch>]
11+
'git-rebase' [-i | --interactive] [-v | --verbose] [--merge] [-C<n>]
12+
[-p | --preserve-merges] [--onto <newbase>] <upstream> [<branch>]
1213
'git-rebase' --continue | --skip | --abort
1314

1415
DESCRIPTION
@@ -208,6 +209,14 @@ OPTIONS
208209
context exist they all must match. By default no context is
209210
ever ignored.
210211

212+
-i, \--interactive::
213+
Make a list of the commits which are about to be rebased. Let the
214+
user edit that list before rebasing.
215+
216+
-p, \--preserve-merges::
217+
Instead of ignoring merges, try to recreate them. This option
218+
only works in interactive mode.
219+
211220
include::merge-strategies.txt[]
212221

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

229-
Author
238+
INTERACTIVE MODE
239+
----------------
240+
241+
Rebasing interactively means that you have a chance to edit the commits
242+
which are rebased. You can reorder the commits, and you can
243+
remove them (weeding out bad or otherwise unwanted patches).
244+
245+
The interactive mode is meant for this type of workflow:
246+
247+
1. have a wonderful idea
248+
2. hack on the code
249+
3. prepare a series for submission
250+
4. submit
251+
252+
where point 2. consists of several instances of
253+
254+
a. regular use
255+
1. finish something worthy of a commit
256+
2. commit
257+
b. independent fixup
258+
1. realize that something does not work
259+
2. fix that
260+
3. commit it
261+
262+
Sometimes the thing fixed in b.2. cannot be amended to the not-quite
263+
perfect commit it fixes, because that commit is buried deeply in a
264+
patch series. That is exactly what interactive rebase is for: use it
265+
after plenty of "a"s and "b"s, by rearranging and editing
266+
commits, and squashing multiple commits into one.
267+
268+
Start it with the last commit you want to retain as-is:
269+
270+
git rebase -i <after-this-commit>
271+
272+
An editor will be fired up with all the commits in your current branch
273+
(ignoring merge commits), which come after the given commit. You can
274+
reorder the commits in this list to your heart's content, and you can
275+
remove them. The list looks more or less like this:
276+
277+
-------------------------------------------
278+
pick deadbee The oneline of this commit
279+
pick fa1afe1 The oneline of the next commit
280+
...
281+
-------------------------------------------
282+
283+
The oneline descriptions are purely for your pleasure; `git-rebase` will
284+
not look at them but at the commit names ("deadbee" and "fa1afe1" in this
285+
example), so do not delete or edit the names.
286+
287+
By replacing the command "pick" with the command "edit", you can tell
288+
`git-rebase` to stop after applying that commit, so that you can edit
289+
the files and/or the commit message, amend the commit, and continue
290+
rebasing.
291+
292+
If you want to fold two or more commits into one, replace the command
293+
"pick" with "squash" for the second and subsequent commit. If the
294+
commits had different authors, it will attribute the squashed commit to
295+
the author of the last commit.
296+
297+
In both cases, or when a "pick" does not succeed (because of merge
298+
errors), the loop will stop to let you fix things, and you can continue
299+
the loop with `git rebase --continue`.
300+
301+
For example, if you want to reorder the last 5 commits, such that what
302+
was HEAD~4 becomes the new HEAD. To achieve that, you would call
303+
`git-rebase` like this:
304+
305+
----------------------
306+
$ git rebase -i HEAD~5
307+
----------------------
308+
309+
And move the first patch to the end of the list.
310+
311+
You might want to preserve merges, if you have a history like this:
312+
313+
------------------
314+
X
315+
\
316+
A---M---B
317+
/
318+
---o---O---P---Q
319+
------------------
320+
321+
Suppose you want to rebase the side branch starting at "A" to "Q". Make
322+
sure that the current HEAD is "B", and call
323+
324+
-----------------------------
325+
$ git rebase -i -p --onto Q O
326+
-----------------------------
327+
328+
Authors
230329
------
231-
Written by Junio C Hamano <[email protected]>
330+
Written by Junio C Hamano <[email protected]> and
331+
Johannes E. Schindelin <[email protected]>
232332

233333
Documentation
234334
--------------

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ SCRIPT_SH = \
204204
git-fetch.sh \
205205
git-ls-remote.sh \
206206
git-merge-one-file.sh git-mergetool.sh git-parse-remote.sh \
207-
git-pull.sh git-rebase.sh \
207+
git-pull.sh git-rebase.sh git-rebase--interactive.sh \
208208
git-repack.sh git-request-pull.sh git-reset.sh \
209209
git-sh-setup.sh \
210210
git-tag.sh git-verify-tag.sh \

git-commit.sh

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -483,34 +483,8 @@ fi >>"$GIT_DIR"/COMMIT_EDITMSG
483483
# Author
484484
if test '' != "$use_commit"
485485
then
486-
pick_author_script='
487-
/^author /{
488-
s/'\''/'\''\\'\'\''/g
489-
h
490-
s/^author \([^<]*\) <[^>]*> .*$/\1/
491-
s/'\''/'\''\'\'\''/g
492-
s/.*/GIT_AUTHOR_NAME='\''&'\''/p
493-
494-
g
495-
s/^author [^<]* <\([^>]*\)> .*$/\1/
496-
s/'\''/'\''\'\'\''/g
497-
s/.*/GIT_AUTHOR_EMAIL='\''&'\''/p
498-
499-
g
500-
s/^author [^<]* <[^>]*> \(.*\)$/\1/
501-
s/'\''/'\''\'\'\''/g
502-
s/.*/GIT_AUTHOR_DATE='\''&'\''/p
503-
504-
q
505-
}
506-
'
507-
encoding=$(git config i18n.commitencoding || echo UTF-8)
508-
set_author_env=`git show -s --pretty=raw --encoding="$encoding" "$use_commit" |
509-
LANG=C LC_ALL=C sed -ne "$pick_author_script"`
510-
eval "$set_author_env"
511-
export GIT_AUTHOR_NAME
512-
export GIT_AUTHOR_EMAIL
513-
export GIT_AUTHOR_DATE
486+
eval "$(get_author_ident_from_commit "$use_commit")"
487+
export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
514488
fi
515489
if test '' != "$force_author"
516490
then

0 commit comments

Comments
 (0)