60

我在 git 存储库中有一个文件,其中有一个本地更改。我想让 git 永远忽略本地更改,而不是文件。尤其,

  • 如果除此更改之外未触及文件,则git add .不应暂存它。
  • 同样,git commit -a不应提交。
  • 如果我对文件进行了额外的更改,我应该能够暂存并提交该更改 - 但我忽略的更改应该暂存和提交。

有没有办法做到这一点?做了一些研究,我读到了“涂抹/清洁周期”,如果我没看错的话,

  1. 该文件将被标记为未更改,
  2. 我所做的更改将在我结帐时被覆盖,
  3. 然后脚本会自动重新应用更改,然后再次将文件标记为未更改。

不过,我对 git 和脚本编写非常陌生(我是一名具有 C# 和 Java 经验的实习生),所以如果这是我需要做的,您能否发布详细的说明或指向如何设置涂抹的教程的链接/clean 循环起来?

背景:我希望我的工作分支与主干不同步。有一个只影响开发机器的低优先级错误,所以我们没有修复它,只是注释掉有问题的代码。显然,我们不希望从生产环境中删除这段代码,因为它工作得很好。

4

9 回答 9

54

您可以使用该skip-worktree位。打开它:

git update-index --skip-worktree <file>

之后,<file>如果 git 本身必须写入<file>(例如,在合并或结帐中),git 将永远不会进行本地更改并且将失败(大声)。

如果您想进行未来的更改,可以将其关闭,进行新的更改,然后重新打开:

git update-index --no-skip-worktree <file>
git add -p <file>
git update-index --skip-worktree <file>

虽然并不完美,但这可能已经足够了。是否有未暂存的更改由您自己决定<file>,因为 git 不会再告诉您

注意:我最初的建议是使用assume-unchanged. 正如Git - 'assume-unchanged' 和 'skip-worktree' 之间的区别中所解释的,这确实skip-worktree是您想要的。特别是,assume-unchanged向 Git 承诺您不会更改文件,如果您违反该承诺,Git 将被允许删除您的更改或提交它们!相反,Git 不会删除或提交您的skip-worktree更改。

于 2013-05-17T04:14:21.760 回答
22

这些答案很好,但可能不能最好地解决@Kevin 的问题。我也有类似的担忧,经常编辑配置文件,因此我正在开发的应用程序将访问我自己的私有开发数据库,​​而不是生产数据库。我不小心签入并推送这些配置更改只是时间问题!我只需要一种轻量级的方式来忽略文件。这是我学到的:

  • 首先,对文件进行所需的更改。我会打电话my_config的。

  • 制作该更改的补丁文件git diff >../somewhere-else/my_config.patch

  • 现在告诉 git 忽略该文件(无需更改签入的 .gitignore):git update-index --assume-unchanged my_config

现在,只要您不更改my_config确实想要签入的内容,您就可以自由工作。停止忽视my_config,做git update-index --no-assume-unchanged my_config。将其他人的更改拉入 后my_config,您可以轻松地使用 恢复您的私人更改git apply ../somewhere-else/my_config.patch,然后...再次假设 - 未更改,如上,然后重新开始工作!

这里有一些有用的别名,你可以在你的~/.gitconfig:

[alias]
    unchanged = update-index --assume-unchanged
    changed = update-index --no-assume-unchanged
    show-unchanged = !"git ls-files -v | sed -e 's/^[a-z] //p; d'"
于 2018-03-19T18:30:00.613 回答
6

Git 的“补丁模式”非常适合仅将文件中的某些更改添加到您的提交中。

要启动它,请键入git add -p, git commit -p(完成后直接提交消息)或git add --interactive(更多提示)。

它实质上会带您浏览显示的每一段代码,git diff并询问您是否要暂存它。

当您进行更改时,请回答n o 或e以在 $EDITOR 中打开补丁。

于 2013-05-17T04:25:18.043 回答
2

注意:其他人说保留持久的本地更改是一个坏主意,我没有任何理由不同意。考虑其他选择。

这是我喜欢的方法:

  1. 进行一些您希望保留在本地计算机上的更改。
  2. 使用git branch localandgit checkout local为您的本地更改创建一个新分支。(如果我没记错的话,这些命令不会自动设置远程分支,所以新分支不会被推送。)
  3. 用于git commit提交您的更改。
  4. 进行要推送到上游的更改。
  5. 用于git checkout parent返回到您确实要推送的分支。
  6. 用于git commit提交到此分支。
  7. 用于git push推送您的更改。
  8. 用于git checkout local返回您当地的分支机构。
  9. 用于git rebase parent将更改从parentin 带到local。使用rebase将使您的本地更改保持在parent.
  10. 回到第 4 步并重复恶心。

有了这个,您不必每次想要进行非本地更改时手动告诉 git 哪些更改是本地的,哪些不是。

于 2015-01-21T21:23:42.783 回答
1

是的,这可能可以使用涂抹/清洁过滤器来完成。但是,我强烈建议不要这样做,因为它会相当复杂且容易出错(例如,它会混淆许多基于 git 构建的工具,它会使问题难以调试等)。

此外,进行永久性本地更改通常不是一个好主意。使用 SCM 的一个重要点是您可以签出一个版本并让它立即工作。这意味着您需要的所有东西都应该检查。

我认为没有任何“好”的方法可以做到这一点,无论是使用 git 还是使用大多数其他 SCM。我建议您重新考虑您的要求。

问题似乎是您有一个包含“混合内容”的文件:一些内容始终相同,而一些内容需要在本地更改(特定于机器的选项?)。处理此问题的推荐方法不是签入有问题的文件,而是签入“模板”文件,然后在构建时生成真实文件。试着调查一下。现在(可能)会做更多的工作,但会让事情变得更容易,特别是如果你需要支持更多的变化或者其他人想要在同一个项目上工作。

编辑(基于评论中的信息)

您写道,您想忽略仅对开发机器必要的本地代码更改,而不是在生产中。

在这种情况下,不要注释掉,而是将代码包装在某种条件中,以便它只在开发机器上运行(例如,使用条件编译,或读取配置文件或某些环境属性,或者...(1 ))。然后就可以正常签入代码了。

更好的是,只需修复错误。如果错误使开发变得困难,那么恕我直言,它是高优先级的。

仅仅注释掉代码并不是一个好主意。这很容易出错,每次结账时都必须这样做。最重要的是,在开发和生产中运行不同的代码是自找麻烦,应尽可能避免。

(1) 举个例子:在我们公司,我们有一个专门针对这种情况的环境变量。它指示代码是在开发、beta 测试还是生产中运行,并由我们的构建和部署脚本设置。但是,它通常只用于简单的事情,比如选择不同的文件路径。如上所述,不鼓励根据环境更改程序逻辑。

于 2013-05-17T07:37:03.113 回答
0

正如我所看到的,您所描述的情况是:您想要维护一个与本地存储库不同的工作目录。

这是不可取的;因为这些更改没有提交,如果文件被意外删除或以您不希望的方式更改,您将几乎没有追索权。

因此,建议您实际上提交所有更改。如果您想分离这些更改,您可以使用分支轻松地做到这一点。例子

git checkout -b new-branch
# now you can change the file without affecting master
echo bar >> foo
git add
git commit
# and back to master
git checkout master
于 2013-05-17T03:57:48.527 回答
0

如果您不能使用 .gitignore 因为您需要在同一个文件中进行并行更改(如您的评论中所见),那么一个选项是 git add -p 使用它您可以相应地添加或跳过。

在这里使用上述 git 命令的问题是,这将是一个手动过程。我猜你可能找不到任何其他自动化方法来解决你的问题。

于 2013-05-17T05:59:05.843 回答
0

从 Git 2.5(2015 年 7 月)开始,您可以使用git worktree

git worktree add -b patch-1 ../patch-1

这本质上只是创建一个分支,但它将新分支放入父 repo 旁边的新文件夹中。这很好,因为你可以在这个分支上工作,即使没有提交,然后切换回 master 并使用干净的工作目录。

于 2016-01-24T03:02:54.897 回答
0

如果您碰巧使用 intellij 作为您的 IDE,那么它有一个简洁的功能(更改列表),我相信它完全符合 OP 的要求。

您可以标记和命名本地差异的特定部分。如果有记忆,这将使这些更改与所有其他本地修改分开,并且只有在您主动选择这样做时才会暂存以进行提交 - 只要您从 intellij 进行提交。

于 2018-02-19T10:25:37.753 回答