Git 在合并时删除 .gitignore 文件?

Git deleting .gitignore files on merge?

我正在尝试遵循此 workflow。 但我有问题。这是交易: 我开始我的回购与 master 跟踪一些文件。 我立即分支到开发分支。 后来我了解到不应跟踪这些文件(Wordpress 核心文件......我正在学习)所以我将它们添加到 .gitignore 文件中。 现在,我已准备好发布,所以我分支到一个版本中进行一些微调。

所以情况是这样的:Master 仍在跟踪文件(它只有一次提交)。 release/1.0 没有跟踪文件。

现在我正在尝试将我的发布分支合并回 master,但是当我这样做时,它会删除我所有未跟踪的文件,而不是仅仅保留它们。

这就是我正在尝试的:

git checkout master
git merge release/1.0

您的一个提交删除了这些文件。因此,直接合并只会应用此提交并删除文件。相反你可以做

git checkout master
git merge --no-ff --no-commit release/1.0
git checkout HEAD <deleted-files>
git commit

这样你就可以强制合并提交并在提交前暂停。
也许您还应该再次从 .gitignore 中删除文件。

现在这些文件仅由 master 分支再次跟踪,每次后续合并都应该正常工作。

据我所知,.gitignore 只是指定 git 不应在 git status 输出中将忽略的文件建议为未跟踪或已修改。如果您手动添加它们,它们将像往常一样被跟踪。反之亦然:如果您删除了一个分支中的一些文件,然后尝试将该分支合并回其原始位置(我认为这就是您所处的情况),那么 git 将在合并时删除这些文件。

示例如下:

alex@galene ~/tmp/tmp5 $ git init
Initialized empty Git repository in /home/alex/tmp/tmp5/.git/
alex@galene ~/tmp/tmp5 $ echo "initial" >file    
alex@galene ~/tmp/tmp5 $ echo "some" >file.bad
alex@galene ~/tmp/tmp5 $ git add file*
alex@galene ~/tmp/tmp5 $ git commit -m "initial"
[master (root-commit) c400ed7] initial
  2 files changed, 2 insertions(+)
create mode 100644 file
create mode 100644 file.bad
alex@galene ~/tmp/tmp5 $ git checkout -b branch
Switched to a new branch 'branch'

更改 "payload" 文件并将更改提交到 branch

alex@galene ~/tmp/tmp5 $ echo "c" >file
alex@galene ~/tmp/tmp5 $ git commit -m "branch commit" file
[branch 3eba064] branch commit
  1 file changed, 1 insertion(+), 1 deletion(-)
alex@galene ~/tmp/tmp5 $ echo "*.bad" > .gitignore
alex@galene ~/tmp/tmp5 $ echo "branch change" >file.bad 
alex@galene ~/tmp/tmp5 $ git status 
On branch branch
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

请注意 file.bad 仍被跟踪

     modified:   file.bad

  Untracked files:
   (use "git add <file>..." to include in what will be committed)

     .gitignore

  no changes added to commit (use "git add" and/or "git commit -a")
alex@galene ~/tmp/tmp5 $ git add .gitignore 
alex@galene ~/tmp/tmp5 $ mv file.bad file.bad.copy; git rm -f file.bad; mv file.bad.copy file.bad
rm 'file.bad'
alex@galene ~/tmp/tmp5 $ git status 
On branch branch
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

       new file:   .gitignore
       deleted:    file.bad

 alex@galene ~/tmp/tmp5 $ git commit -m "remove file.bad from version control but leave in the worktree"
 [branch b4c1d42] remove file.bad from version control but leave in the worktree
   2 files changed, 1 insertion(+), 1 deletion(-)
   create mode 100644 .gitignore
   delete mode 100644 file.bad
alex@galene ~/tmp/tmp5 $ git checkout master
Switched to branch 'master'

执行对 master

的提交
alex@galene ~/tmp/tmp5 $ echo "master change" >file
alex@galene ~/tmp/tmp5 $ git commit -m "master change" file
[master 78142c8] master change
  1 file changed, 1 insertion(+), 1 deletion(-)
alex@galene ~/tmp/tmp5 $ git merge --no-commit branch
Removing file.bad
Auto-merging file
CONFLICT (content): Merge conflict in file
Automatic merge failed; fix conflicts and then commit the result.
alex@galene ~/tmp/tmp5 $ git status 
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")

Changes to be committed:

         new file:   .gitignore
         deleted:    file.bad

 Unmerged paths:
  (use "git add <file>..." to mark resolution)

         both modified:   file

正如您在最后一步中看到的那样,您在 file 中删除了 file.bad 和(预期的)冲突。所以你可以在合并之前存储在某个地方file.bad(例如cp file.bad file.bad.copy然后在合并之后恢复它)。

以下是我所做的工作:

  1. 在 master 中,我修改了 .gitignore 文件以反映 release/1.0 中的 .gitignore 文件并提交。
  2. 使用 git rm --cached <file> 从跟踪中删除了我添加到 .gitignore 的相同文件并再次提交。
  3. 然后我合并成功了

更新: 在更好地了解整个情况后,我能够更准确地 google 并在 SO 上找到一个措辞更好的问题和答案:Git: How to remove file from index without deleting files from any repository

虽然它是在谈论不同的回购协议,而不是像我处理的不同分支,但我相信问题是一样的。