git checkout & git pull:执行时避免中间文件更改

12

我很惊讶竟然找不到任何关于这个的资料...

简而言之,我的问题是:是否有一种方法可以避免在下面两个命令之间进行中间文件更改,如果在下面两个命令之后,文件内容与之前完全相同?

git checkout dev
git pull

这个动机是(即使只能满足一个动机,也比什么都不做要好):

  • 我想避免我的IDE在不需要的情况下重新加载文件(是的,VS项目文件...)。
  • 避免对没有真正更改的文件进行存储。

这是当我从特性分支回到主分支时,在使用远程源代码控制服务器将origin/feature合并到origin/dev之后的常见情况。

我希望在执行git fetch origin dev之前能解决这个问题,但事实并非如此。我还发现了一些答案,比如这篇文章,它谈到了将命令分组以便操作,但没有解决文件更改问题。


1
我很惊讶这个问题的兴趣如此之少,我认为每个使用Git的人都会想要一个解决方案。 - Christopher Hamkins
2个回答

9

我也遇到了同样的情况,经过寻找一个更简单的替代方法,我终于找到了需要的内容:

拉取另一个分支而不切换:

如果将分支B合并到分支A中会产生非快进合并,就无法在没有先检出A的情况下进行合并。 这是因为需要一个工作副本来解决潜在的冲突。

此命令仅适用于快进合并。

git fetch origin master:master

(使用您想要更新的分支替换master。在 OP 的情况下,将是 git fetch origin dev:dev)

一旦本地分支与远程更改同步,您可以切换到所需分支而不会引起文件更改。

参考资料:


1
有一种方法可以实现这个,使用git worktree add。确保您的Git至少为2.5(以便具有git worktree),最好至少为2.15(修复了一个相当严重的添加工作树错误;如果没有修复,添加的工作树通常不应使用超过两周)。
您的IDE可能与git worktree add不兼容;我避免使用IDE,因此无法说哪些IDE与之合作,哪些不合作。
假设您有支持添加工作树的Git版本,请使用git worktree add创建您的dev分支,并将主工作树保留在master分支上。或者,将添加的工作树用于主要(master或其他)分支,将主工作树用于dev分支。请记住,Git强制每个工作树都有不同的分支选中。
停止使用git pull。(这不是绝对必要的,但我建议这样做。)

要从服务器更新您的存储库,请随时使用git fetch—在任何工作树中没有额外参数。这将获取它们拥有但您没有的任何新提交,并更新您的origin/*远程跟踪名称。

要更新您的master分支,请进入master分支的工作树,然后在命令行上运行git mergegit merge origin/master。(如果您最近没有这样做,请先运行git fetch以便具有最新的origin/master。)

要更新您的dev分支,请进入dev分支的工作树,然后在命令行上运行git mergegit merge origin/dev。与之前一样,如果您最近没有运行git fetch,则可能需要这样做,以使您的origin/master处于最新状态。

您的IDE可能无法实现命令行的功能。根据IDE的不同,也许可以在每个工作树中运行两份副本。

请记住,git pull 只是运行 git fetch 然后运行 git merge(或者 git fetch 然后运行 git rebase)。是 git checkout 扰乱了你的工作树文件的时间戳。Git 实际上并不使用或需要工作树:这是为了而存在的。运行 git checkout 会用其他提交中的文件替换工作树中的文件,同时还会用其他提交中的文件替换索引中的文件;索引副本是 Git 使用和关心的文件。

Git 替换工作树文件是因为它假设您需要从要切换到的分支中获取这些文件。当然,切换回来会再次更新这些工作树文件。所以现在各种文件已经更新了两次,需要重新构建。


当你添加一个新的工作树时,Git实际上添加了三个项目组:
  • 为新工作树添加一个新的HEAD,以记住当前提交和/或分支是新工作树中的当前提交;
  • 为新工作树添加一个索引,Git用于存储下一个可能进行的提交的Git文件;以及
  • 新的工作树本身,供您查看和处理文件。
这个工作树只是一个在主仓库工作树之外的目录(或文件夹)。例如,如果您的主仓库位于~/work/project,则可以将其移动到~/work/project/main,并创建~/work/project/dev来保存dev分支的工作树。
然而,从根本上说,问题很简单:当您使用git checkout时,Git根据需要替换索引和工作树内容。因此,您需要停止使用git checkout。如果您需要两个工作树,请制作两个单独的工作树。
如果您的Git版本过旧,不支持工作树,请创建两个克隆。除了两个克隆不共享分支外,其他所有内容都是相同的。

谢谢,我稍后会尝试理解细节。只是为了澄清 - 你的意思是IDE可能与这个解决方案兼容也可能不兼容?我的意思是,我不介意手动运行命令而不使用GUI(我通常都这样做),你是说如果不兼容就应该使用命令行吗? - MaMazav
我的意思是,有些IDE可能无法“理解”添加工作树的概念。它可能会坚持认为只有一个工作树,即主要的工作树。这个新功能在Git中只有大约3.5年的历史(我提到的重大错误也只在2017年末得到修复),因此它可能不支持它。 - torek
谢谢你的回答。对我来说,这个解决方案似乎比我尝试解决的问题要复杂,但是知道这个概念还是很好的,如果有需要的话。谢谢! - MaMazav
较新的提议解决方案非常简单... 在执行 git checkout dev 命令之前,先运行 git fetch origin dev:dev 命令(使用 ":" 语法)- 对我来说似乎很有效,如果这个方法对你也有用,那么可以接受该答案!专业提示:理论上,你甚至可以创建自己的 git 别名,以减少输入命令的次数 ^^ - T_D
@T_D:请注意,git fetch origin br:br 只进行快进(正如该答案中已经提到的),因此如果您需要进行真正的合并,则不适用。此外,如果您只想要 br 所指向的新提交,您可以直接运行 git fetch origin,然后直接使用 origin/br。这样您就不必担心是否有 br 分支了! - torek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接