在git中进行“临时”提交的最佳方法是什么?

时间:2010-10-17 13:54:18

标签: git temporary

假设我有一个带有两个分支master和dev的项目。我在dev上提交了一系列特殊事件的提交,这些特殊事件曾经测试过并合并到master中。然后在事件结束后我想删除特定于事件的代码。但是,由于自添加事件代码以来已进行了其他提交,因此无法执行git重置。

目前我使用git checkout来检查合并事件之前的文件,然后使用git diff重新添加自事件提交以来所做的更改。这对我来说似乎是一种非常混乱的方法。

有没有人有更好的解决方案在项目中使用临时代码?

编辑: 要明确的是,需要提交,推送,未提交,推送更改。

7 个答案:

答案 0 :(得分:18)

掌握并创建分支:git checkout -b special-event,制作/应用您的更改。事件结束后,只需切换回master并放弃/删除分支。

为了继续进行更改,请在master上进行更改并将它们合并到特殊分支中。 git checkout master ...进行更改... git checkout special-event; git merge master

或者,在一次提交中进行所有与特殊事件相关的更改,然后在想要将它们推出时使用git revert并指定该提交。

答案 1 :(得分:2)

"临时代码"?在git中我们使用分支。提交在git中是非常轻量级的,而分支,只是附加了一点逻辑的提交的名称(或引用),与其他系统相比是超轻量级的。

一点点逻辑就是引用自动更新到最后一次提交。这几乎就是分支的全部内容。这意味着在git中创建和销毁分支是快速,简单甚至安全的,因为没有真正创建或删除任何内容。在删除之后,您仍然可以通过commit-id引用分支头(是的,它仍然存在,直到它被垃圾收集,甚至只有在没有其他参考的情况下才会发生这种情况)。

几乎git中的每个命令都将对commit的引用作为参数。 git合并也是如此。您没有合并分支,您正在合并提交。是的,您输入了#git merge',但同样,分支只是提交的名称。没有比这更好的了。因为你需要的只是将事件的提交分组在一起,所以只需给它们起一个名字。

所以正确的做法是为活动创建一个分支。或者可能是两个:' event-master'和' event-dev'。现在,您在' event-dev'中为事件开发代码。如果您遇到需要在主代码中修复的错误,请隐藏并切换到您正常的“开发”代码。分支,代码修复和提交。切换回' event-dev',从' dev'合并,然后弹出藏匿处。继续开发,一旦完成,提交和测试。如果没问题,请合并“event-dev'进入' event-master'。这也包含修复。请注意,此修复程序不在“#master;'爱好。

如果您需要将修复程序合并到' master'中,您只需按常规方式执行此操作,因为修复程序位于' dev'。

基本上在此设置中,您可以:

  • 像往常一样开发主要代码:您承诺开发'测试并合并到' master';

  • 以类似的方式开发特定于事件的代码:您承诺参与' event-dev',测试并合并到' event-master&#39 ;;它只是一样的工作流程;

  • 混合两个工作流程;提交和切换分支,或使用git stash;

  • 自由地合并分支(几乎);你可以合并' master'进入' event-dev',如果master以某种方式更新,你需要对事件进行更改;你可以合并' dev'进入' event-dev',如果您迫切需要对事件进行更改,并且无法等待将其推入主人的常规测试周期。只要合并是干净的,git就会这样做,除非你在两个-dev分支中以两种不同的方式改变了同一段代码(这当然是一个需要处理的特殊情况);

如果您需要额外的灵活性,请创建更多分支。为了获得超级灵活性,您可以将个别提交分配到一个分支中,但总的来说,我建议不要这样做(只有当您真正知道自己在做什么时才这样做。)

最后,我应该指出,这个工作流程在git中非常自然。实际上,在&dev;开发中开发并且在“主人”中拉动变化一般来说,甚至不是最好的。习惯上为您正在开发的每个功能或模块创建一个开发分支,并在“开发”中合并这些分支。

我认为使用git时的正确心态是:"我今天想要编码什么?特征X.好的,让我们创建分支' feature-x'并开始黑客攻击。"。你的那件事也不例外。

现在,我知道我告诉你的是你应该从一开始就做些什么,而且现在对此没什么帮助。您需要修复您的树,因为 - 看起来 - 您将事件的更改与正常更改混合到您的' dev'科。所以你的问题是如何正确地创建事件开发者'仅对事件进行更改并将其从“开发”中删除在同一时间。

重写历史的时间。这将是多么艰难,这取决于变化的性质。例如,如果所有更改都属于单个目录,则事情会更容易。

这是我要做的事情(不知道更好):

  • 使用git log检查历史记录;

  • 在第一次特定事件更改之前找到提交,注意其commit-id:这是' day-0'提交;

  • 创建一个名为' newdev'指着那个提交。在干净的树中执行此操作,即在执行此操作之前提交:git checkout< commit-id> -b newdev;

  • 创建' event-dev&#39 ;: git checkout -b event-dev;

  • 你现在有两个分支都指向了第0天&0;提交;

  • 现在再次查看历史记录(git log dev),你需要按照提交的方式进行提交;

  • 我假设每次提交都是在第0天和第0天之后进行的。是属于主代码的提交,还是属于该事件的提交。你要做的就是在正确的分支中挑选它们,并且新的'如果它是主要代码,那么事件 - 开发者'如果是它的事件代码;按照正确的顺序(从'第0天到第39天到今天)进行一次;

  • 如果你非常幸运,那么最终没有任何提交最终会出现在&new;取决于事件 - 开发中的提交'反之亦然;你已经完成了;你可能想要重命名(保持它们)当前的master和dev到master-old和dev-old,然后将newdev重命名为dev,从dev创建master,从event-dev创建event-master,然后你设置

  • 如果你运气不那么幸运,有时候你不得不合并“newdev'进入' event-dev',因为一些提交取决于主代码中所做的更改,这很好,但是;如果你在这里感觉大胆,那么现在是时候阅读git rebase;但除非你必须,否则不要退缩;

  • 或者(更糟糕的)“newdev'如果主分支需要,那么特定于事件的代码就不是特定于事件的,取决于事件 - 开发' ... oops的变化。需要一些合并;

  • 或(坏)一个提交包含两种类型的更改:分而治之(您需要将更改分开并将它们应用于正确的分支),这意味着您将提交分成两部分;

  • 或其他我现在无法想象的东西,因为我没有足够的关于你的树的细节。

这可能是微风或噩梦。事先检查每个提交(git show,你可以把它看作一个补丁),决定做什么(最终不要挑选,只是编辑文件可能更容易),如果不确定 - 猜猜是什么 - 创建一个分支,在那里工作,看看会发生什么,如果开心就合并它,否则再放下它再试一次。

到目前为止我还没有提到它,但当然你可以制作整张树的副本,包含git文件,并在副本上工作100%安全。

从一开始就做得很容易。现在解决它,好吧,祝你好运。 :)

答案 2 :(得分:1)

git checkout -b event

...进行特定的事件更改......

git commit -am "specific event change"

...进行另一项具体事件变更......

git commit -am "another specific event change"

此时,分支仍然完好无损,特定于事件的更改位于事件分支上。如果对事件分支中也需要的主分支进行了更改,请使用 rebase ...

git rebase master

另一个答案建议将合并到事件,但 rebase 通常是更好的方法。 rebase 剥离主题分支上的提交,拉出更新后的,然后在顶部重新应用主题分支更改...就像主题分支更改一样是最新版本的主人。

在您的方案中,当事件结束时,只需删除事件分支。

答案 3 :(得分:1)

按照我的非专利方法汇总您的提交:

# work on a new branch
git checkout -b event-36
git commit -a -m "all broken dammit"
git commit -a -m "fixed that damn code"
git commit -a -m "almost ready, going to eat lunch"
git commit -a -m "It's done!"

# other people might be working on master in the meantime, so
git checkout master
git checkout -b erasemeImmediately
git merge event-36
git reset --soft master # THE KEY TO THE WHOLE THING: SOFT RESET!
git commit -a -m "Event 36, all code in one commit"

git checkout master
git merge erasemeImmediately

您可以使用reflog执行此操作,但是您需要最近的CS学位(即,很难理解)。

现在你的提交是一个单独的提交。现在你可以使用还原或樱桃选择没有它的分支。

答案 4 :(得分:0)

git revert

它将删除您需要撤消的任何提交或提交范围。推向公共回购也是安全的。

答案 5 :(得分:0)

根据我的经验,一些特殊事件有一种反复出现的方式。因此,这里要考虑的替代解决方案是创建一个配置选项以启用处理特殊事件,以便可以在需要时打开和关闭它。

答案 6 :(得分:-1)

我相信stash会做你想要的。

相关问题