• Aucun résultat trouvé

Using git rebase -i

Dans le document Version Control with Git (Page 185-189)

Let’s say you start writing a haiku and manage to compose two full lines before checking it in:

A B C D E master

W X

P Q

Y Z maint

feature Figure 10-14. Before git rebase transplant

A B C D E master

W X

P Q

Y Z maint

feature

Figure 10-15. After git rebase transplant

Rebasing Commits | 167

$ git init

Initialized empty Git repository in .git/

$ git config user.email "jdl@example.com"

$ cat haiku Talk about colour No jealous behaviour here

$ git add haiku

$ git commit -m"Start my haiku"

Created initial commit a75f74e: Start my haiku 1 files changed, 2 insertions(+), 0 deletions(-) create mode 100644 haiku

Your writing continues, but you decide you really should use the American spelling of

“color” instead of the British spelling. So, you make a commit to change it:

$ git diff

$ git commit -a -m"Use color instead of colour"

Created commit 3d0f83b: Use color instead of colour 1 files changed, 1 insertions(+), 1 deletions(-)

Finally, you develop the final line and commit it:

$ git diff

$ git commit -a -m"Finish my colour haiku"

Created commit 799dba3: Finish my colour haiku 1 files changed, 1 insertions(+), 0 deletions(-)

However, you have again a spelling quandary and decide to change all British “ou”

spellings to the American “o” spelling:

$ git diff

-No jealous behaviour here -I favour red wine +No jealous behavior here +I favor red wine

$ git commit -a -m"Use American spellings"

Created commit b61b041: Use American spellings 1 files changed, 2 insertions(+), 2 deletions(-)

At this point, you’ve accumulated a history of commits that looks like this:

$ git show-branch --more=4 [master] Use American spellings [master^] Finish my colour haiku [master~2] Use color instead of colour [master~3] Start my haiku

After looking at the commit sequence or receiving review feedback, you decide that you prefer to complete the haiku before correcting it and want the following commit history:

[master] Use American spellings [master^] Use color instead of colour [master~2] Finish my colour haiku [master~3] Start my haiku

But then you also notice that there’s no good reason to have two similar commits that correct the spellings of different words. Thus, you would also like to squash the master and master^ into just one commit.

[master] Use American spellings [master^] Finish my colour haiku [master~2] Start my haiku

Reordering, editing, removing, squashing multiple commits into one, and splitting a commit into several are all easily performed by the git rebase command using the -i or --interactive option. This command allows you to modify the commits that make up a branch and place them back onto the same branch or onto a different branch.

A typical use, and the one apropos for this example, modifies the same branch “in place.” In this case, there are three changesets between four commits to be modified.

git rebase -i needs to be told the name of the commit beyond which you actually intend to change:

$ git rebase -i master~3

You will be placed in an editor on a file that looks like this:

pick 3d0f83b Use color instead of colour pick 799dba3 Finish my colour haiku pick b61b041 Use American spellings

# edit = use commit, but stop for amending

# squash = use commit, but meld into previous commit

#

# If you remove a line here THAT COMMIT WILL BE LOST.

# However, if you remove everything, the rebase will be aborted.

#

The first three lines list the commits within the editable commit range you specified on the command line. The commits are initially listed in order from oldest to most recent and have the pick verb on each one. If you were to leave the editor now, each commit would be picked (in order), applied to the target branch, and committed. The lines preceded by a # are helpful reminders and comments that the program ignores.

At this point, however, you are free to reorder the commits, squash commits together, change a commit, or delete one entirely. To follow the steps just listed, simply reorder the commits in your editor as follows and exit it:

pick 799dba3 Finish my colour haiku pick 3d0f83b Use color instead of colour pick b61b041 Use American spellings

Recall that the very first commit for the rebase is the “Start my haiku” commit. The next commit will become “Finish my colour haiku,” followed by the “Use color...” and

“Use American...” commits:

$ git rebase -i master~3

# reorder the first two commits and exit your editor Successfully rebased and updated refs/heads/master.

$ git show-branch --more=4 [master] Use American spellings [master^] Use color instead of colour [master~2] Finish my colour haiku [master~3] Start my haiku

Here, the history of commits has been rewritten; the two spelling commits are together and the two writing commits are together.

Still following the outlined order, your next step is to squash the two spelling commits into just one commit. Again, issue the git rebase -i master~3 command. This time, convert the commit list from:

pick d83f7ed Finish my colour haiku pick 1f7342b Use color instead of colour pick 1915dae Use American spellings

to:

pick d83f7ed Finish my colour haiku pick 1f7342b Use color instead of colour squash 1915dae Use American spellings

The third commit will be squashed into the immediately preceding commit, and the new commit log message template will be formed from the combination of the commits being squashed together.

In this example, the two commit log messages are joined and offered in an editor:

# This is a combination of two commits.

# The first commit message is:

Use color instead of colour

# This is the 2nd commit message:

Use American spellings

The message can be edited down to just:

Use American spellings

Again, all # lines are ignored.

Finally, the results of the rebase sequence can be seen:

$ git rebase -i master~3

# squash and rewrite the commit log message Created commit cf27784: Use American spellings 1 files changed, 3 insertions(+), 3 deletions(-) Successfully rebased and updated refs/heads/master.

$ git show-branch --more=4 [master] Use American spellings [master^] Finish my colour haiku [master~2] Start my haiku

Although the reordering and squash steps demonstrated here occurred in two separate invocations of git rebase -i master~3, the two phases could have been performed in one. It is also perfectly valid to squash multiple sequential commits into one commit in a single step.

Dans le document Version Control with Git (Page 185-189)