简体   繁体   English

重新打开上次提交

[英]Reopen last commit

I like to an have overview of my current code changes in unstaged (or staged) files before a commit.我喜欢在提交之前概述未暂存(或已暂存)文件中的当前代码更改。 But in the end of the day I commit even not working code and send it as a Work In Progress to Gerrit to have a backup of my work.但在一天结束时,我什至提交了不工作的代码,并将其作为正在进行的工作发送给 Gerrit,以备份我的工作。

The other day I would like to "reopen" the commit to continue the work.前几天我想“重新打开”提交以继续工作。 This means that I would like to have yesterdays state just before commit, but I don't want abandon the commit as it is already sent to Gerrit.这意味着我希望在提交之前有昨天的状态,但我不想放弃提交,因为它已经发送给 Gerrit。 I would like to have the same files unstaged and HEAD pointing to the current commit in order to amend the changes when code is working and may be commited.我希望将相同的文件取消暂存,并将 HEAD 指向当前提交,以便在代码工作时修改更改并且可以提交。

This code almost works, just I end up with HEAD one commit before:这段代码几乎可以工作,只是我在 HEAD 之前提交了一次:

touch file

git commit -am 'Work in progress commit'

git reset --soft HEAD~1

If I use git commit --amend I would edit different (previous) commit.如果我使用git commit --amend我会编辑不同的(以前的)提交。

If I use git commit -am 'Work in progress commit' I would create different commit from the yesterdays.如果我使用git commit -am 'Work in progress commit'我会创建与昨天不同的提交。 And yesterdays will be lost (but not in Gerrit).昨天将会丢失(但不会在 Gerrit 中)。

Commits in git are immutable. git 中的提交是不可变的。 This is not a convention that any tool can bypass or work around, it is fundamental to the way git works: a commit is identified by a hash of its contents, so any change in the contents is guaranteed to result in a different identifier.这不是任何工具都可以绕过或解决的约定,它是 git 工作方式的基础:提交由其内容的哈希值标识,因此内容的任何更改都保证会产生不同的标识符。

Branches, on the other hand, are movable pointers to a commit.另一方面,分支是指向提交的可移动指针。 You can create a branch, create a work in progress commit, and then repoint the same branch to a new commit later.您可以创建一个分支,创建一个进行中的提交,然后稍后将同一分支重新指向一个新的提交 That is in fact what git commit --amend or git reset --soft followed by git commit will do.这实际上就是git commit --amendgit reset --soft后跟git commit会做的。

To share the new version, you need to use git push --force-with-lease (or the older and slightly less safe git push --force ) - be very careful doing this for shared branches, but use it as much as you want for a branch that everyone knows you "own".要共享新版本,您需要使用git push --force-with-lease (或较旧且安全性稍差的git push --force ) - 对共享分支执行此操作时要非常小心,但尽可能多地使用它想要一个每个人都知道你“拥有”的分支。

Alternatively, you can just keep adding more commits to the working branch.或者,您可以继续向工作分支添加更多提交。 At the end of the task, you might want to use git rebase -i to squash some of them into a "tidier" history;在任务结束时,您可能想使用git rebase -i将其中一些压缩成“更整洁”的历史记录; or you might not bother, and just leave the chain of intermediate commits as a record of your thought processes.或者您可能不会打扰,而只是将中间提交链作为您思维过程的记录。

When and how to branch and commit is subjective, but objectively if you want to avoid having those "WIP" commits in your log (for instance, when contributing to someone else's project where your final pull request should be clean), here's one strategy you can use:何时以及如何分支和提交是主观的,但客观地说,如果您想避免在您的日志中提交那些“WIP”提交(例如,当为其他人的项目做出贡献时,您的最终拉取请求应该是干净的),这是您的一种策略可以使用:

  1. When starting something, create a branch.开始某件事时,创建一个分支。 Let's call it feature/the-thing .我们称它为feature/the-thing
  2. When you're about to do a series of things you expect to take a couple of days, branch feature/the-thing to feature/the-thing-wip ( W ork I n P rogress).当你准备做一系列你预计需要几天feature/the-thing时,将 feature/the-thing 分支到feature/the-thing-wip ( W ork I n Progress)。
  3. Commit and push early and often to feature/the-thing-wip .尽早并经常提交并推送到feature/the-thing-wip
  4. When you're ready for a "real" commit to feature/the-thing , merge feature/the-thing-wip into it with --squash (or just merge to the working tree and then commit that) with a useful commit message saying what you did during the WIP.当您准备好对feature/the-thing进行“真正的”提交时,使用 --squash 将feature/the-thing-wip --squash合并到其中(或者只是合并到工作树然后提交)以及有用的提交消息说出你在 WIP 期间做了什么。 (Optional: Delete the feature/the-thing-wip branch.) (可选:删除feature/the-thing-wip分支。)
  5. Repeat as appropriate until the branch is complete.适当重复,直到分支完成。
  6. Either merge feature/the-thing with your main branch or send the pull request using feature/the-thing .feature/the-thing与您的主分支合并,或者使用feature/the-thing发送拉取请求。

The result is that feature/the-thing only has the "real" commits.结果是feature/the-thing只有“真正的”提交。


<subjective>In projects you're not coordinating with lots of other people, there's no need for that WIP branch. <subjective>在您不与很多其他人协调的项目中,不需要 WIP 分支。 Just branch, commit early and often, then merge as normal.</subjective>只需分支,尽早并经常提交,然后正常合并。</subjective>

Well, with the help of TJ.好吧,在TJ的帮助下。 Crowder and IMSoP I found this quite cumbersome solution. Crowder 和 IMSoP 我发现这个解决方案相当麻烦。 But works fine.但工作正常。

git rebase -i HEAD~1 // or more for editing more commits back git rebase -i HEAD~1 // 或更多用于编辑更多提交

In the interactive mode editor choose the commit to edit and replace 'pick' with 'edit', save and exit在交互模式编辑器中选择要编辑的提交并将“pick”替换为“edit”,保存并退出

git reset --soft HEAD~1

Now, you see the your work in progress as if you never commited it before.现在,您看到正在进行的工作,就好像您以前从未提交过一样。 Make your changes.进行更改。

git add *

git status // find a hash in "Last command done:" git status // 在“最后完成的命令:”中找到一个散列

git reset --soft <hash>

git rebase --continue

git push origin HEAD:refs/for/master%wip

If you open now web interface of your Gerrit server you find that your commit (and all following) have a new patchset.如果您现在打开 Gerrit 服务器的 Web 界面,您会发现您的提交(以及所有后续提交)都有一个新的补丁集。

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

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