67

我正在寻找一种方法来“隐藏”对 Git 中的几个文件所做的微小更改,这样它们就不会在 git status 中显示,直到对这些文件进行不同的更改。

示例:我有一个 java 文件,其中所做的唯一更改是删除未使用的导入(贡献者在提交之前忘记运行组织导入)。现在我已经删除了该导入并且更改(显然)显示在 git 中。由于我没有对该文件进行其他更改,因此我真的不喜欢将文件作为另一个(不相关)更改的一部分提交或单独提交此更改。当然,我可以恢复更改,并且只在我必须对该文件进行更改时应用它,但我可能会“冒险”忘记它。

这样的任务是否存在命令?它的工作方式有点像假设不变的命令,但不是永久的。

如果没有这样的命令可用,解决此问题的正确方法是什么?

提前致谢。

4

6 回答 6

102

在我的用例中(在我的个人机器上使用编辑过的配置文件进行开发,在另一台具有未更改配置的机器上运行),这是我的解决方案:

开始忽略对文件的更改:

git update-index --assume-unchanged path/to/file

再次跟踪:

git update-index --no-assume-unchanged path/to/file
于 2014-10-24T14:07:42.590 回答
4

只是不要添加微不足道的更改。

在提交之前仔细检查您添加的内容是一种很好的做法。

您甚至可以在添加其他更改时忽略文件中的某些更改,使用

git add -p.

如果您使用gitx (R) ,这会更容易。

于 2013-02-11T16:35:05.440 回答
3

将未准备好的更改保存在单独的分支中。git rebase必要时,此分支位于主要历史记录中的新更改之上。

无论是正在进行的开发、临时的事情,甚至是永远不会包含在主要项目历史中的事情——同样的过程同样有效。

如果/何时分支的更改准备好包含在主历史记录中;将其合并。如果没有,请将它们保留在单独的分支中并继续变基。

(旁注:git merge --no-ff即使可以进行快进合并,也可能用于创建合并提交——根据您的项目规则,这可能更可取)

于 2013-02-11T15:04:55.457 回答
3

使用的缺点git update-index --assume-unchanged是(如git 手册所述),您向 git 保证您不会更改文件。

当“假设不变”位打开时,用户承诺不更改文件并允许 Git 假设工作树文件与索引中记录的内容匹配。

如果您违反此承诺并更改文件,则可能会产生不良后果。例如,在某些实现中,执行 agit stash将丢弃您对文件所做的更改(如果您承诺不会更改它,为什么不应该这样做?)。

使用--skip-worktree选项告诉 git 假装工作版本与索引版本是最新的。

在读取条目时,如果它被标记为 skip-worktree,那么 Git 会假装其工作目录版本是最新的,并改为读取索引版本。

这似乎是忽略更改的更可靠的方法,而不会有某些 git 命令可能会丢弃您的更改的风险:

git update-index --skip-worktree path/to/file

再次跟踪文件:

git update-index --no-skip-worktree path/to/file

要列出您设置的文件skip-worktree

git ls-files -v | grep ^S
于 2021-03-02T14:03:04.273 回答
1

我在这里添加了所有答案,以添加一些让我的生活更舒适的代码。期望 BSD coreutils(如在 MacOS 上)。

git-overlook

#!/usr/bin/env bash

path="$1"
root="$(git rev-parse --show-toplevel)"

if [ -z "$path" ]; then
  echo "Specify a path" 1>&2
  exit 1;
fi;

if [ ! -d .git/overlook ]; then
    mkdir $root/.git/overlook
fi;
record="$root/.git/overlook/$(echo $path | sed 's/\./___/g' | sed 's/\//____/g')"
touch "$record"
git update-index --skip-worktree "$path"

git-relook

#!/usr/bin/env bash

path="$1"
root="$(git rev-parse --show-toplevel)"

record="$root/.git/overlook/$(echo $path | sed 's/\./___/g' | sed 's/\//____/g')"
if [ -f "$record" ]; then
  git update-index --no-skip-worktree "$path"
  rm "$record"
fi;

最后一个.git/hooks/pre-commit

#!/bin/bash

set -eu

root="$(git rev-parse --show-toplevel)"

get_record_name() {
  record="$root/.git/overlook/$(echo $1 | sed 's/\./___/g' | sed 's/\//____/g')"
  echo "$record"
}

for file in $(git ls-files -v | grep ^S | sed 's/S //'); do
  record="$(get_record_name $file)"
  record_mtime="$(stat -f %m $record)"
  file_mtime="$(stat -f %m $file)"

  if [ "$record_mtime" -lt "$file_mtime" ]; then
    echo "File $file is overlooked but has been modified since. Please run either git overlook $file or git relook $file" 1>&2
    exit 1
  else
    echo "File $file is overlooked but hasn't been modified"
  fi;

done;

这使得我可以运行git overlook path/to/file,然后我可以继续以我快乐的方式提交,直到我更改了被忽略的文件,此时我必须再次忽略它或将它带回来git relook path/to/file。显然,如果忽略的文件是我所做的唯一更改,然后我在git status.

它会制作一些文件.git/overlook来跟踪内容,但据我所知,git它将与它们和平共存。

于 2021-11-23T03:39:25.213 回答
0

有多种方法[虽然可能不干净整洁,需要您注意]

  1. 将相关文件添加到.gitignore您的存储库中,以便它不会出现提交。.gitignore当您准备好提交文件时,请小心删除它
  2. 确保在提交其余更改时不要“暂存”文件。您可能想要编写一个包装器git,以确保命令喜欢git commit -agit add .在所有文件上运行,但有问题的文件除外。另一种选择是使用git gui或者git citool您可以在视觉上确保您的文件不在“暂存”区域中,因此永远不会被提交
  3. 另一种方法是提交所有“可提交”更改,然后提交git stash save唯一的工作文件。稍后当您准备好更改文件时,您可以git stash pop继续工作和提交。

希望有帮助:)

于 2012-11-18T16:55:39.837 回答