【问题标题】:How to prevent checked-in files from overwriting local versions?如何防止签入的文件覆盖本地版本?
【发布时间】:2016-10-12 00:25:06
【问题描述】:

我对签入文件进行了一些特定于平台的修改。当我从远程分支合并时,如何强制 git 保留本地版本并忽略远程版本?基本上,就像 git-ignore,但是对于已经被存储库跟踪的文件。

用例是我推送到一个分支,然后将这个分支拉到不同的平台上进行测试。第一次在每个平台上进行测试需要运行 ./configure 脚本,该脚本使用特定于平台的自定义修改了一些文件。由于这些更改是自动生成的,我不想将它们提交给历史。通常我将这些文件添加到 .gitignore,但是,其中一些文件是原始存储库的一部分,因此 git ignore 将被忽略。

【问题讨论】:

  • 将它们放入您的 git exclude 文件 (.git/info/exclude) 是否适合您的用例?
  • 这样会阻止签入的文件覆盖本地版本吗?
  • 只有在您取消跟踪修改/生成的文件时才会这样做。如果您想跟踪它们,skip-worktree 标志可能会有所帮助。有关示例,请参阅此答案及其链接参考。 stackoverflow.com/a/13631525/149428

标签: git github


【解决方案1】:

这是一种可能的解决方案。

假设git merge之前的原HEAD为A,合并后运行git checkout A -- path_of_the_file_you_want_to_keep,将文件恢复为A的状态。

但这会使工作树变得不干净。如果您运行git status,您会发现索引中的文件已更改。我认为这是不可避免的,除非你再次提交。

由于原始 HEAD 由 git 中的变量 ORIG_HEAD 引用,因此无论 A 的实际 sha1 是什么,您始终可以运行 git checkout ORIG_HEAD -- path_of_the_file_you_want_to_keep

【讨论】:

  • 我是否需要先提交在 ./configure 运行之后发生的所有平台特定修改,然后才能签出这些文件?
  • 我不清楚您的要求,但我认为这取决于。您可以提交任何您想要保留和恢复的更改。
【解决方案2】:

不要签入。以不同的名称签入模板,并忽略活动文件的名称。

如果您的项目需要一个名为(例如)config.txt 的文件,请将该文件名放入 .gitignore,然后将具有不同名称的文件(例如 config.sample.txt)检查到存储库中。如果您想变得花哨,可以让您的应用程序自动将文件从 config.sample.txt 复制到 config.txt(如果该文件尚不存在)。

【讨论】:

  • 我正在 fork 一个现有项目,并且这些文件已经签入。它们正在被 ./configure 脚本修改,所以大概需要一些东西已经存在
  • 所以 git mv 将文件从其当前名称更改为新名称,并修改 configure 脚本以复制文件,就像我在回答中解释的那样。
  • 这是configure script btw
【解决方案3】:

这可能是 git pull keeping local changes 的副本,因为如果不提交特定于平台的更改,那么那里的第一个答案似乎是最好的解决方案。

【讨论】:

  • 顺便说一句,如果您碰巧在 Mac 上,这 (git stash && git pull && git stash pop) 就是 Tower 在拉取时对分阶段和非分阶段更改所做的事情。
  • @tedmiston 你怎么知道 Tower 是这样做的?我试图弄清楚如何在没有运气的情况下查看 Tower 命令日志
  • @YaroslavBulatov 他们似乎没有将所有内容都打印到活动日志中,尽管我相信描述执行这些命令的提示。我发现他们的客户支持非常好,如果您需要明确的确认,我相信他们会提供。
猜你喜欢
  • 1970-01-01
  • 2016-01-05
  • 2019-07-07
  • 1970-01-01
  • 2013-06-06
  • 1970-01-01
  • 2015-09-27
  • 2013-03-24
  • 2022-12-16
相关资源
最近更新 更多