简体   繁体   中英

Git deleting .gitignore files on merge?

I am trying to follow this workflow . But I am having issues. Here's the deal: I started my repo with master tracking some files. Immediately I branched into a develop branch. I later learned that those files should not be tracked (Wordpress core files...I'm learning) so I added them to the .gitignore file. Now, I am ready for a release, so I branched off into a release for some fine tuning.

So the situation is this: Master is still tracking the files(it only has a single commit). And release/1.0 is not tracking the files.

Now I am trying to merge my release branch back into master, but when I do that it deletes all my untracked files, instead of just leaving them be.

This is what I'm trying:

git checkout master
git merge release/1.0

One of your commits deleted these files. So a straightforward merge will only apply this commit and delete the files. Instead you could do

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

This way you force a merge commit and halt before commiting.
Maybe you should also remove the files from .gitignore again.

Now these files are only traked by the master branch again and every successive merge should work just fine.

As far as I remember .gitignore simply specifies that git shouldn't propose ignored files as untracked or modified in the git status output. If you add them manually they will be tracked as usual. And vice versa: if you remove some files in a branch and then try to merge that branch back to its origin, (this is the situation you are in, I think), then git will remove those files on merge.

Here's the example:

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'

change the "payload" file and commit the changes to the 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)

Notice that file.bad is still tracked

     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'

perform a commit to 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

As you may see on the last step you get the removal of file.bad and (expected) conflict in the file . So you may store somewhere file.bad before the merge (eg cp file.bad file.bad.copy and then restore it after the merge).

Here's what I did that worked:

  1. In master I modified the .gitignore file to reflect the .gitignore file in release/1.0 and committed.
  2. Removed the same files from tracking that I added to .gitignore, using git rm --cached <file> and committed again.
  3. Then I did the merge successfully.

Update: After better understanding the whole situation I was able to google more precisely and found a better worded question and answer here on SO: Git: How to remove file from index without deleting files from any repository

Although it is talking about different repos and not different branches like I dealt with, I believe the issue is the same.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM