简体   繁体   English

在执行git-svn dcommit之前压缩或编辑一些提交?

[英]Squashing or editing some commits before doing git-svn dcommit?

I am working on a project in a subversion repository with a strict check-in policy which includes: Every commit to the trunk has to be reviewed by another developer and this must be mentioned in the commit message. 我正在使用严格的签入策略在subversion存储库中处理项目,其中包括:每次提交到trunk都必须由另一个开发人员审核,这必须在提交消息中提及。

While working with git-svn I am making many incremental git check-ins that aren't reviewed. 在使用git-svn时,我正在进行许多未经审核的增量git签到。 Their git commit messages reflect this. 他们的git commit消息反映了这一点。

What's the best way in which to use git-svn but follow the rules for the svn repository? 使用git-svn但遵循svn存储库规则的最佳方法是什么? Should I just squash all commits into a single svn commit? 我应该将所有提交压缩成单个svn提交吗? Can I rewrite the commit messages for each revision with the reviewer information? 我可以使用审阅者信息重写每个修订的提交消息吗? Could I "manually" move each individual change to the git master branch and modify the commit message of each before doing a git-svn dcommit? 在执行git-svn dcommit之前,我可以“手动”将每个单独的更改移动到git master分支并修改每个更改的提交消息吗?

I work in a branch on git, then checkout master, git svn rebase and finally merge the branch into master. 我在git的分支上工作,然后checkout master, git svn rebase ,最后将分支合并到master中。

At this point, git svn dcommit will put all the interim commits into svn one at a time with their original messages — not what's wanted! 在这一点上, git svn dcommit会将所有临时提交一次性放入svn中,并使用原始消息 - 而不是想要的! But if I use git commit --amend to change the merge's commit message from the standard merge message to something that fits our policy for svn commits, the dcommit will lump them all together as one under the new message. 但是如果我使用git commit --amend将合并的提交消息从标准合并消息更改为适合我们的svn提交策略的东西,那么dcommit会将它们全部归为新消息下的一个。 Win. 赢得。

I've found that this doesn't seem to work if master hasn't changed over the lifetime of the branch — the commits just get fast-forwarded in, with no "merged branch" message — so it's best add the --no-ff flag to git merge . 我发现如果master在分支的生命周期内没有改变,这似乎不起作用 - 提交只是快速转发,没有“合并分支”消息 - 所以最好添加--no-ff标志为git merge

Summary: 摘要:

git checkout branch
<do work>
git checkout master
git svn rebase
git merge --no-ff branch
git commit --amend
<policy-compliant commit message>
git svn dcommit

You can interactively rebase your local branch against the Subversion tracking branch which provides you with an opportunity to squash and amend the commit. 您可以使用Subversion跟踪分支以交互方式对本地分支进行重新绑定,从而为您提供压缩和修改提交的机会。

Next time you dcommit, dcommit will replay your history one commit at a time and this is what will be commited to Subversion. 下次你提交时,dcommit将一次重放你的历史记录,这将是Subversion的提交。

Assumptions: 假设:

  1. Local branch is master 本地分支是主人
  2. Master is checked out 师父已退房
  3. Remote tracking branch is named git-svn 远程跟踪分支名为git-svn
  4. git-svn is up to date git-svn是最新的

What to do: 该怎么办:

$ git rebase -i git-svn

Your default editor will open with a list of commits in master to rebase against git-svn. 您的默认编辑器将打开,其中包含master中的提交列表以反对git-svn。 You can pick, edit or squash the commit (Mix and match if desired). 您可以选择,编辑或压缩提交(如果需要,可以混合和匹配)。

After making your selection, another temporary file will open displaying commit messages for each of the commits you're rewriting. 进行选择后,将打开另一个临时文件,显示您正在重写的每个提交的提交消息。 This is where you amend the commit message. 这是修改提交消息的地方。

Caveats: 注意事项:

You're rewriting the history of your repository, exercise caution. 您正在重写存储库的历史记录,请谨慎操作。 It might be worthwhile experimenting with this behaviour until feel confident. 在感到自信之前,尝试这种行为可能是值得的。

Yes, you can rewrite the commit messages. 是的,您可以重写提交消息。 Yes, you can just squash them all in to a single commit. 是的,你可以将它们全部压缩到一次提交中。 This probably depends on the review process and how much you're doing at once. 这可能取决于审核流程以及您一次完成的工作量。

"Manually" moving each change to the master branch wouldn't be especially different from rewriting your commit messages at some level, but many diverging branches and cherry-picks could come in handy. “手动”将每个更改移动到主分支与在某个级别重写提交消息没有特别的不同,但是许多不同的分支和樱桃选择可能会派上用场。

Overall, the answer is "it depends" and "Git is flexible enough to do just about whatever you need". 总的来说,答案是“它取决于”和“Git足够灵活,可以做任何你需要的事情”。

This might be worth a try, I'm a relative newbie but this is what I'm doing for now: 这可能值得一试,我是一个相对新手,但这就是我现在正在做的事情:

Create a clone of the remote svn repository: 创建远程svn存储库的克隆:

# clone svn repository
git svn clone ....

Create a normal git repository (clone of the clone): 创建一个普通的git存储库(克隆克隆):

# clone the clone :)
git clone /path/to/original/clone
git checkout -b working

You can now work in the second clone as though it were a normal git repository (essentially it is): 您现在可以在第二个克隆中工作,就好像它是一个普通的git存储库(实际上它是):

# commit changes, whatever you like
git ci
...

To push your changes back to the central SVN repository go back to the first clone and: 要将更改推送回中央SVN存储库,请返回第一个克隆并:

# pull and flatten changes
git pull --squash /path/to/working/clone

The --squash parameter means that all the commits that are pulled in are merged into one commit. --squash参数表示所有提交的提交都合并到一个提交中。 That commit is not committed immediately so you can then: 该提交不会立即提交,因此您可以:

git ci
git svn dcommit  

The last step then pushes everything as one single commit. 最后一步然后将所有内容推送为单个提交。

Edit - I wouldn't normally recommend using --squash in other circumstances but note that the working repository retains the full complete history (it's immune to the squash) but what you send upstream is squashed into a single clean commit which is what is needed in this case. 编辑 - 我通常不会建议在其他情况下使用--squash ,但请注意工作存储库保留完整的完整历史记录(它不受壁球影响),但是您向上游发送的内容被压缩为一个干净的提交,这是需要的在这种情况下。 I believe it to be a reasonable compromise. 我认为这是一个合理的妥协。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM