Gerrit/拆分提交的更改

This page is a translated version of the page Gerrit/split a submitted change and the translation is 26% complete.
Outdated translations are marked like this.

有时候,人们提交的大补丁本来应该以小补丁的形式提交。 本页将帮助您了解如何在Gerrit中拆分已提交的更改并正确地重新提交。 这个页面使用了一个真实的案例,发生在2012年3月,当我们从subversion迁移到git时,它基于Gerrit change 3497引入了三个不同的变化:缓存助手,一种格式化时间持续时间的方法和一些双引号到单引号的转换。

协议真的很简单,获取变更,创建一个新的分支,然后在它上面选择变更。 然后只添加你感兴趣的部分。 对更改的所有部分重复相同的过程。

获取代码

确保你是最新的主存储库:

git checkout master
git pull --rebase

接下来我们要做的是从Gerrit中获取代码。 最简单的方法是使用git-review:

git:master)$ git-review -d 3497
Downloading refs/changes/97/3497/5 from gerrit into review/catrope/cachedpage
Switched to branch 'review/catrope/cachedpage'
git:review/catrope/cachedpage)$

Then find out the commit sha1 introduced by that change using the git log command. We simply have to output commits which makes HEAD different from master:

review/catrope/cachedpage)$ git log --oneline master..HEAD
367d8f5 Resubmit the entire SpecialCachedPage/formatDuration saga as one big com
review/catrope/cachedpage)$

Now create the topic branch and apply the patch locally

git:review/catrope/cachedpage)$ git checkout master -b cachedpage
Switched to a new branch 'cachedpage'
git:cachedpage)$ git show --no-color 367d8f5 | git apply -
$ git status
# On branch cachedpage
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	modified:   includes/AutoLoader.php
#	modified:   languages/Language.php
#	modified:   languages/messages/MessagesEn.php
#	modified:   languages/messages/MessagesQqq.php
#	modified:   maintenance/language/messages.inc
#	modified:   tests/phpunit/languages/LanguageTest.php
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#	includes/CacheHelper.php
#	includes/actions/CachedAction.php
#	includes/specials/SpecialCachedPage.php
no changes added to commit (use "git add" and/or "git commit -a")
git:cachedpage)$

You now have to pick the chunk we are interesting in to create a new commit which be used for the "cachedpage" topic. To add a file, one would use git add as usual, git add --patch to select chunks inside a file. When even you want to skip a file, just reset it with git checkout -- FILENAME, this way they will not clutter the output of git status while you are looking for additional chunks to stage.

Once you have finished staging files and change for the topic. Review the staged difference git diff --cached and commit it. Eventually fill in the original author name by using git commit --amend --author "FirstName LastName <someone@example.org>".

For the second topic, it is very similar. Create a new branch and apply the patch that need to be split:

git:cachedpage)$ git checkout master -b formatduration
Switched to a new branch 'format duration'
git:formatduration)$ git show --no-color 367d8f5 | git apply -

Now we can get rid of any code which has already been committed under the previous topic "cachedpage", to do so we will apply it as a reverse patch:

$ git show cachedpage | git apply --reverse -
error: patch failed: maintenance/language/messages.inc:3935
error: maintenance/language/messages.inc: patch does not apply
$ 

You will have to carefully look at the patch to fix that. In this case, that is because we had to manually edit a chunk to split the code between the cachedpage and the formatduration topics. Git reject a patch by default, we can forces it with --reject:

git:formatduration)$ git show cachedpage | git apply --reverse --reject -
Checking patch includes/AutoLoader.php...
Checking patch includes/CacheHelper.php...
Checking patch includes/actions/CachedAction.php...
Checking patch includes/specials/SpecialCachedPage.php...
Checking patch languages/messages/MessagesEn.php...
Checking patch languages/messages/MessagesQqq.php...
Checking patch maintenance/language/messages.inc...
error: while searching for:
	'logging-irc'           => 'For IRC, see bug 34508. Do not change',
	'feedback'              => 'Feedback',
	'apierrors'             => 'API errors',
	'cachedspecial'         => 'SpecialCachedPage',
);

error: patch failed: maintenance/language/messages.inc:3935
Applied patch includes/AutoLoader.php cleanly.
Applied patch includes/CacheHelper.php cleanly.
Applied patch includes/actions/CachedAction.php cleanly.
Applied patch includes/specials/SpecialCachedPage.php cleanly.
Applied patch languages/messages/MessagesEn.php cleanly.
Applied patch languages/messages/MessagesQqq.php cleanly.
Applying patch maintenance/language/messages.inc with 1 rejects...
Hunk #1 applied cleanly.
Rejected hunk #2.
git:formatduration)$

Looking at the working copy status already show that the cache related files have been removed, already saving sometime. --reject generated a file named .rej

git:formatduration)$ git status
# On branch formatduration
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	modified:   languages/Language.php
#	modified:   languages/messages/MessagesEn.php
#	modified:   maintenance/language/messages.inc
#	modified:   tests/phpunit/languages/LanguageTest.php
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#	maintenance/language/messages.inc.rej

It contains a line related to cachedpage.

Then start adding the files and chunk you are interested in with git add and git add --patch. Then commit and set the original author (same as above).

This specific case only had three mixed topic. What is remaining in your working copy is the third change. So crafting a commit for it is even easier:

git checkout -b quotes master
git add tests/phpunit/languages/LanguageTest.php
git commit --author <SOMEONE>

submitting

The three topics can be seen with:

git:quotes)$ git log --graph --decorate --oneline --all
* 5605bf3 (HEAD, quotes) change double quotes to single quotes
| * 5200440 (formatduration) duration formatter, makes time in sec easy to read
|/  
| * e2ef042 (cachedpage) CacheHelper: facilitate caching handling on a page
|/  
* d859541 (gerrit/master, master) Use local context to get messages
| * 367d8f5 (review/catrope/cachedpage) Resubmit the entire SpecialCachedPage/fo
|/  
*   458f162 Merge "[LanguageConverter] Added some cache code based on the proble 
<snip>

So we have the three topic branches based on master and we can now submit them all. Checkout each of them and submit them using git-review:

git:master)$ git checkout cachedpage
Switched to branch 'cachedpage'
git:cachedpage)$ git-review --no-rebase -f
remote: Resolving deltas:  14% (2/14)
remote: 
remote: New Changes:
remote:   https://gerrit.wikimedia.org/r/c/mediawiki/core/+/4628
remote: 
To gerrit.wikimedia.org
 * [new branch]      HEAD -> refs/for/master/cachedpage
Switched to branch 'master'
Deleted branch 'cachedpage'


git:master)$ git checkout formatduration
Switched to branch 'formatduration'
amusso@aeriale:/srv/trunk(git:formatduration)$ git-review --no-rebase -f
remote: Resolving deltas:   0% (0/12)
remote: 
remote: New Changes:
remote:   https://gerrit.wikimedia.org/r/c/mediawiki/core/+/4629
remote: 
To gerrit.wikimedia.org
 * [new branch]      HEAD -> refs/for/master/formatduration
Switched to branch 'master'
Deleted branch 'format duration'


git:master)$ git checkout quotes
Switched to branch 'quotes'
git:quotes)$ git-review --no-rebase -f
remote: Resolving deltas:   0% (0/5)
remote: 
remote: New Changes:
remote:   https://gerrit.wikimedia.org/r/c/mediawiki/core/+/4630
remote: 
To gerrit.wikimedia.org
 * [new branch]      HEAD -> refs/for/master/quotes
Switched to branch 'master'
Deleted branch 'quotes'
git:master)$