git储藏式流行合并解决冲突和理性

发布于 2025-01-24 11:45:23 字数 511 浏览 3 评论 0 原文

我最近一直在使用 git stash git pull git stash pop 当我需要同步到其他什么时,我的工作流程开发人员正在做,但请首先保存我的工作,然后继续工作。我最近做了一个 git拉以使一切新事物毫无问题,我被赶上了。几个小时后,我做了藏匿/拉动/弹出声,并在执行 git pop 时得到了合并冲突。我看到冲突是在我很久以前写过的代码之间,以及我目前试图从干净的拉和这一数字之间的几个小时来拉动的冲突。

这可能是因为我从过去解决了合并冲突后没有清理藏匿处,因此随后的POP +冲突试图使用发生冲突的最新储藏?

我想我的意思是,如果您遇到冲突并在弹出藏匿处解决了冲突,您是否需要手动删除该藏匿处,以避免下次弹出冲突时?我认为藏匿处的弹出声应该去除藏匿处,但是如果发生冲突,我就不会这样做……因此,需要手动完成它,以避免它试图让我解决我之间的冲突我最近做的拉力和几周前完成并推动的代码?

只是想弄清楚这一点并避免它。

I've recently been using git stash, git pull, and git stash pop as my work flow when I need to sync up to what other devs are doing, but save what I'm working on first, and then continue working. I recently did a git pull to get everything new and it worked with no problem, I was caught up. A few hours later I did stash/pull/pop and and got a merge conflict when doing the git pop. I saw that the conflicts were between code I recognized I had written a long time ago and what I was trying to currently pull from just a couple hours in between the clean pull and this one.

Could this be because I didn't clear my stash after I resolved a merge conflict from the past, therefore any subsequent pop + conflict tries to use the most recent stash where a conflict also occurred?

I guess what I'm saying is, if you get a conflict and resolve it after popping your stash, do you need to manually remove that stash to avoid this next time you pop with conflict? I thought stash pop was supposed to remove the stash, but I take it it doesn't if there's a conflict... so it needs to be done manually to avoid the unexpected situation where it was trying to get me to resolve conflicts between the recent pull I did and code that was done and pushed weeks ago?

Just trying to figure this out and avoid it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

自演自醉 2025-01-31 11:45:23

我想我要问的是,如果您在藏匿藏处后发生冲突并解决了冲突,您是否需要手动删除该藏匿处,以免下次弹出冲突时?

否。但是,这个部分是正确的:

我认为藏匿处的流行声应该删除藏匿处,但是如果有冲突,我就不会接受……

关于 git stash ,有一些关键的事情,一旦您知道它们,您可以(就像我一样)决定避免 git Stash 。第一个也是最重要的是:所有 git stash push 确实做出一些提交。

提交 git stash (使用保存或保存或push动词)是在 no 分支上,这在某种程度上很方便,但它们也有一些内部奇数,这使它们不便:只有 git stash stash 命令才能交易这些提交正确正确。这一切都意味着,只要以普通的方式做普通的奉献,就无法获得任何您无法获得的东西。有时,特殊的藏匿委员会可能更方便,有时它们可​​能不方便。您应该知道 - 或者至少对此有很强的感觉 - 在运行 git stash 之前将是这种情况,这样您就可以选择是否使用 git stash 根本。

关于 git stash 的第二件事或一组事情是:

  • 它总是至少做出两个提交,有时三个。
  • 所做的承诺有点奇怪。 git将把其中一个视为a 合并commit (因为从技术上讲是合并犯罪),这会使其余的git认为它应该对待该提交,就像是正常合并(哪个不是)。那是为什么您必须使用 git Stash 来处理这些提交。
  • 存储代码实现了所谓的“储藏堆栈”。也就是说, git stash push 将a new stash 添加到 git stash stash pop 将藏匿处那一堆藏匿处。如果您只制作,然后流行,一个藏匿处,您不会在这里看到任何奇怪的东西,但是如果您做两个或多个,您会看到这种“堆栈”行为。
  • git stash pop 操作实际上与运行 git stash apply& amp; git储藏夹。也就是说,POP有两个部分:“应用”步骤,然后 - 如果“应用”实际上是成功的成功 - a drop”步骤。
  • 应用步骤运行 git Merge 操作。像任何合并一样,这可以产生合并冲突。最终结果不是新的合并commit 。见下文。

与普通的投入(永远存在于您的存储库中) 1 掉落的藏匿处可能会永久丢弃,这可能会相对较快地发生。这意味着,如果您使用 git stash pop ,并且git 认为 储存是正确应用的,那么您可能永远无法再看到它 - 即使它是 未正确应用因此,您可能需要使用 git stash应用而不是 git stash pop 。然后,您可以检查应用程序以查看它是否正确到您的标准,而不是git,然后使用 git stash drop 将其销毁。

​这样可以防止 git stash pop 操作执行 git stash drop 步骤。如果合并步骤不产生合并冲突,则GIT考虑应用步骤已成功,无论合并结果是否有意义。 因为GIT的合并规则纯粹是基于文本的,并且在任何更深层次的意义上都不理解 Clooce Clooce depart 不理解。

如果您确实得到合并冲突,则必须手动解决它们或使用 git mergetool 请注意, git Reset -Hard 可用,它可能不会带您回到您期望的文件版本。合并 git git stash应用启动使用文件的当前工作树版本,这些版本不一定与这些文件的订阅版本匹配。普通的 git Merge 要求您的工作树是“清洁” 2 在启动之前尝试,但是 Git Stash 没有此限制。因此,最好完全解决合并。 自行正确地“回头”。

git不能 't详细介绍了很多细节,只会列出以下其他项目符号点:

  • 保存 index 状态和工作树状态。索引(或登台区域)状态总是保存,但是在 git stash应用过程中被忽略,除非您还使用 > - 索引 。因此,您可以在上确定应用(或 pop )时间是否还原已保存的索引。


  • 如果您使用 -a -U ,则有一个第三 commit可以保存未跟踪的文件。

  • 进行两到三个提交后, git stash push 通常运行 git reset-hard ,加上 git git call 如果使用了,代码> -a 或 -U 。确保您知道这些做什么! (尽管 reset 命令非常复杂,但它基本git,应该在工具箱中很早就考虑使用 git git stash 。 )

    有些新的“部分储藏”功能( git stash push 带有Pathspecs,首先在Git 2.13中添加)无法进行此批发,因此没有,但是有很多错误在其中持续了一段时间,因此,除非您的git版本至少为2.26左右,否则我不建议使用部分储藏功能。 (我仍然不相信内部的GIT测试在这里足够,但是它们比GIT 2.13好。)

  • git stash stash 的三个commit版本具有最近引入的新错误数量(大约在Git 2.30左右),我不完全确定它们都固定在Git 2.35和/或2.36中。由于这个和三个储藏的其他问题,我建议尽可能避免它们。

  • 对于艰难的藏匿案例(您已经制作了藏匿处并且现在无法应用它),请考虑使用 git stash branch 将储藏室变成 自己的。如果您创建了一个新的分支,在必要时将索引定为索引,然后准备提交工作树,这样您现在可以提交工作树,并拥有一个普通的提交,可以在普通的情况下使用,这将产生您将获得的东西git处理提交的方式。请注意,您可能需要使用 git stash push 来清理足够的东西,以便此时使用 git stash branch !在那里制作分支并在那里犯下的分支机构要容易得多。

所有这一切的最终结果是,至少我通常更喜欢做一些事情。如果它不是真正的“准备好”,那没什么大不了的:我可以将提交重置,或者我可以为新提交做一个新的分支。这使我获得了一个普通的提交,而不是特殊的怪异 stash@{ number } } 提交需要使用 git stash 来处理它们的提交。


1 好吧,永远或至少30天,以更合适为准。

I guess what I'm [asking] is, if you get a conflict and resolve it after popping your stash, do you need to manually remove that stash to avoid this next time you pop with conflict?

No. However, this part is correct:

I thought stash pop was supposed to remove the stash, but I take it it doesn't if there's a conflict ...

There are a few key things to know about git stash, and once you know them, you may decide (as I did) to mostly avoid git stash. The first and most important thing is this: All git stash push does is make some commits.

The commits that git stash (with the save or push verb) makes are on no branch, which is convenient in a way, but they also have some internal oddities, which makes them inconvenient: only the git stash command can deal correctly with these commits. What this all means is that you're not getting anything you couldn't get by just making ordinary commits in the ordinary way. Sometimes the special stash commits might be more convenient, and sometimes they might be less convenient. You should know—or at least, have a strong sense about it—which of these will be the case before you run git stash, so that you can choose whether to use git stash at all.

The second thing, or group of things, to know about git stash is this:

  • It always makes at least two commits, and sometimes three.
  • The commits it makes are a bit weird. Git will see one of them as a merge commit (because it technically is a merge commit), which will make the rest of Git think that it should treat that commit as if it were a normal merge (which it isn't). That's why you have to deal with these commits using git stash.
  • The stash code implements what it calls a "stash stack". That is, git stash push adds a new stash to the stack, and git stash pop takes a stash off that stack of stashes. If you only ever make, and then pop, a single stash, you won't see anything odd here, but if you make two or more, you'll see this "stack" behavior.
  • The git stash pop operation is literally the same as running git stash apply && git stash drop. That is, there are two parts to a pop: an "apply" step, and then—if and only if the "apply" actually succeeds—a "drop" step.
  • The apply step runs a git merge operation. Like any merge, this can produce merge conflicts. The end result is not a new merge commit, though; see below.

Unlike normal commits, which live forever in your repository,1 a dropped stash may be discarded permanently, and this can happen relatively quickly. This means that if you use git stash pop, and Git thinks the stash was correctly applied, you may not ever be able to see it again—even if it wasn't correctly applied. As a result, you might want to prefer to use git stash apply instead of git stash pop. You can then check the application to see if it's correct to your standards, rather than Git's, and only then use git stash drop to destroy it.

If the merge step that git stash apply runs produces merge conflicts, Git considers the apply to have failed. That is, this prevents the git stash pop operation from doing the git stash drop step. If the merge step does not produce merge conflicts, Git considers the apply step to have succeeded, regardless of whether the merge result makes any sense. Carefully inspect the result of the merge (and/or run tests on it) as Git's merge rules are purely text-based and do not understand files in any deeper sense.

If you do get merge conflicts, you must resolve them by hand or using git mergetool. Note that while git reset --hard is available, it may not bring you back the versions of files you expect. The merge that git stash apply starts uses the current working tree versions of the files, which may not necessarily match the committed versions of those files. A normal git merge requires that your working tree be "clean"2 before it will start, so that git reset --hard can undo the attempt, but git stash does not have this restriction. So it's best to resolve the merge completely. Git cannot "back it out" correctly on its own in general.3

There's a bunch more to know, but I want to keep this particular answer short (at least, short for me), so I won't go into a lot more detail, and will just list these additional bullet points:

  • The two commits save the index state and the working tree state. The index (or staging area) state always gets saved, but is then ignored during git stash apply unless you also use --index. So you decide at apply (or pop) time whether to restore the saved index.

  • If you use -a or -u, there's a third commit that saves untracked files.

  • After making the two or three commits, git stash push normally runs git reset --hard, plus git clean if you used -a or -u. Be sure you know what these do! (Although the reset command is horribly complicated, it is basic Git and should be in your toolbox long before you ever think about using git stash.)

    The somewhat-new "partial stash" feature (git stash push with pathspecs, first added in Git 2.13) can't do this wholesale, so it doesn't, but there were numerous bugs in it for a while, so unless your Git version is at least 2.26 or so I don't recommend using the partial stash feature. (I'm still not convinced the internal Git tests are adequate here, but they're way better than they were in Git 2.13.)

  • The three-commit version of git stash has had a number of new bugs introduced recently (around Git 2.30 or so) and I'm not entirely sure they're all fixed in Git 2.35 and/or 2.36. Because of this and of other issues with three-commit stashes, I recommend avoiding them as much as possible.

  • For tough stash cases (where you've made a stash and are now unable to apply it), consider using git stash branch to turn the stash into a branch of its own. This produces what you would have gotten had you created a new branch, committed the index if necessary, and then been ready to commit the working tree, so you can now commit the working tree and have an ordinary commit that you can use in the ordinary ways that Git handles commits. Note that you might need to use git stash push to clean things up enough to use git stash branch at this point, though! It's a lot easier to have made a branch and committed there earlier.

The end result of all of this is that I, at least, generally prefer to just commit something. If it's not really "ready" to be committed, that's not a big deal: I can just reset the commit away, or I can make a new branch for the new commit. This gets me an ordinary commit, instead of the special weird stash@{number} commits that require using git stash to deal with them.


1Well, forever or at least for 30 days, whichever is more appropriate. ???? It's relatively hard to permanently ditch a commit, but if you "abandon" one—or several—by resetting or deleting a branch name, for instance, commits that are no longer needed do eventually get cleaned out.

2The word "clean" here means that git status would say nothing to commit, working tree clean. ("Clean" unfortunately does not have a single simple reliable definition in all cases, in Git.)

3If your working tree was "clean" at the start, Git would be able to back it out, but in this case git reset --hard will do the trick anyway. If it wasn't "clean", there are some cases that Git would in theory be able to back out, and others that it would not. There's nothing in Git to even try to do it, though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文