Git - Ignore files during merge

154,778

Solution 1

I ended up finding git attributes. Trying it. Working so far. Did not check all scenarios yet. But it should be the solution.

Merge Strategies - Git attributes

Solution 2

I got over this issue by using git merge command with the --no-commit option and then explicitly removed the staged file and ignore the changes to the file. E.g.: say I want to ignore any changes to myfile.txt I proceed as follows:

git merge --no-ff --no-commit <merge-branch>
git reset HEAD myfile.txt
git checkout -- myfile.txt
git commit -m "merged <merge-branch>"

You can put statements 2 & 3 in a for loop, if you have a list of files to skip.

Solution 3

.gitattributes - is a root-level file of your repository that defines the attributes for a subdirectory or subset of files.

You can specify the attribute to tell Git to use different merge strategies for a specific file. Here, we want to preserve the existing config.xml for our branch. We need to set the merge=foo to config.xml in .gitattributes file.

merge=foo tell git to use our(current branch) file, if a merge conflict occurs.

  1. Add a .gitattributes file at the root level of the repository

  2. You can set up an attribute for confix.xml in the .gitattributes file

     <pattern> merge=foo
    

    Let's take an example for config.xml

     config.xml merge=foo
    
  3. And then define a dummy foo merge strategy with:

     $ git config --global merge.foo.driver true
    

If you merge the stag form dev branch, instead of having the merge conflicts with the config.xml file, the stag branch's config.xml preserves at whatever version you originally had.

for more reference: merge_strategies

Solution 4

You could start by using git merge --no-commit, and then edit the merge however you like i.e. by unstaging config.xml or any other file, then commit. I suspect you'd want to automate it further after that using hooks, but I think it'd be worth going through manually at least once.

Solution 5

Example:

  1. You have two branches: master, develop
  2. You created file in develop branch and want to ignore it while merging

Code:

git config --global merge.ours.driver true
git checkout master
echo "path/file_to_ignore merge=ours" >> .gitattributes
git merge develop

You can also ignore files with same extension

for example all files with .txt extension:

echo "*.txt merge=ours" >> .gitattributes
Share:
154,778

Related videos on Youtube

Kevin Rave
Author by

Kevin Rave

Updated on March 04, 2022

Comments

  • Kevin Rave
    Kevin Rave over 2 years

    I have a repo called myrepo on the remote beanstalk server.

    I cloned it to my local machine. Created two additional branches: staging and dev. Pushed these branches to remote as well.

    Now:

     local                   remote                   server
     --------------------------------------------------------  
     master  ==> Pushes to  `master`  ==> deployed to `prod`
     staging ==> Pushes to  `staging` ==> deployed to `staging`
     dev     ==> Pushes to  `dev`     ==> deployed to `dev`
    

    I have a file called config.xml which is different on each branch.

    I want to ignore this file only during merges. But I want this to be included when I checkout or commit from/to the repo branch.

    The reason I want this is, we have a deploy script that pulls (checkout) the specific branch and deploys on the respective servers. So we need config.xml file of that specific branch go into the specific server as indicated above when deployed.

    I guess .gitignore wont work. What are the other options? Note that the ignored file should be part of checkout and commit, which is important. it should be ignored only during merges.

    Thanks!

    • zzk
      zzk over 11 years
      In its default mode, git pull is shorthand for git fetch followed by git merge FETCH_HEAD. So you statements kind of conflict with each other.
    • Kevin Rave
      Kevin Rave over 11 years
      Well, I would say, its checkout. Not pull. I will update the question to be clear.
    • givanse
      givanse over 10 years
    • pvinis
      pvinis almost 8 years
      did you ever find a solution to this? git attributes are only useful for the case where the file has conflicts between the branches being merged, so its not always enough.
    • Frank Nocke
      Frank Nocke over 6 years
      did you look into symbolic (not followed by git) or even hard links to the rescue?
  • Kevin Rave
    Kevin Rave over 11 years
    Does git attributes offer any straight solution? I am not able to understand this. git-scm.com/book/en/…
  • Kevin Rave
    Kevin Rave over 11 years
    I know thats kind of hack. I am trying to find a clean solution. What about git attributes. Any idea how it works? I am not able to understand this. git-scm.com/book/en/…
  • tlehman
    tlehman over 11 years
    I have not heard of these, I'm trying to apply the merge=ours attribute, looks promising.
  • tlehman
    tlehman over 11 years
    Git attributes are awesome! You can even tell git how to diff non-text files, so you could use pdf2text to diff PDFs!
  • Nate-
    Nate- almost 11 years
  • Ilia Shakitko
    Ilia Shakitko about 7 years
    I'd add "--no-ff" if you want a file not be overwritten when merge happens in fast-forward strategy.
  • Rolf
    Rolf over 6 years
    That's nice when pushing but still complains when pulling might overwrite the file.
  • Sireesh Yarlagadda
    Sireesh Yarlagadda over 6 years
    have you tried to add your file entry in .gitignore file. @Rolf
  • Adrian Laurenzi
    Adrian Laurenzi over 6 years
    Here is the correct link for the merge strategies section of the git attributes docs: git-scm.com/book/en/v2/…
  • ShawnFeatherly
    ShawnFeatherly over 6 years
    Found this well explained in an article medium.com/@porteneuve/…
  • Igor Yalovoy
    Igor Yalovoy about 6 years
    But what if there is no conflict? How to always keep a certain file during merge?
  • torek
    torek almost 6 years
    @IgorYalovoy: If there is no conflict ... well, this is a little tricky as it actually works from hash IDs, but: if config.xml is completely unchanged from the merge base to either branch tip version, Git just takes the changed version, without looking at the merge.ours.driver setting. So you are correct to be concerned.
  • Brett
    Brett almost 6 years
    This seems to be a problem if there are no conflicts? Files will still be merged?
  • kyb
    kyb almost 6 years
    copy-paste from Git Docs: Merge Strategies - Git attributes. Link
  • rsmets
    rsmets over 5 years
    This method results in "merge commits" every time FYI.
  • Kid_Learning_C
    Kid_Learning_C almost 5 years
    so what does git reset HEAD myfile.txt do exactly? How does it help with our goal here?
  • Kyle Strand
    Kyle Strand over 4 years
    "ours" appears to be an arbitrary name for the new strategy being introduced. I found this confusing, because theirs is a built-in merge strategy. But it seems that one can write <pattern> merge=foo, then git config --global merge.foo.driver true, and it will work the same way.
  • Johann
    Johann over 4 years
    How do you put lines 2 and 3 in a loop?
  • Zhasulan Berdibekov
    Zhasulan Berdibekov over 3 years
    This is working only in situation where have a conflict!
  • Wawrzyniec Pruski
    Wawrzyniec Pruski over 3 years
    @AndroidDev You can do something like this: for i in `ls myfile.txt myfile_2.txt`; do echo $i; git reset HEAD $i && git checkout -- $i; done
  • Partha Mandal
    Partha Mandal over 3 years
    @Kid_Learning_C : git reset HEAD myfile.txt unstages the file (which was staged post --no-commit merging)
  • ericOnline
    ericOnline about 3 years
    Adding a .gitattributes file to the main branch with <filename-to-exclude> merge=ours, then running git config --global merge.ours.driver true worked great. The config file in dev was not merged into the config file in main. Unfortunately, during the merge the .gitattributes file was deleted (because it did not exist in dev)! How do avoid this? Just add the same .gitattributes file to dev? Would the ours value cause a conflict?
  • ericOnline
    ericOnline about 3 years
    Ended up: Created .gitattributes in dev branch according to above comment, add, commit, push to dev. Checkout main, git merge dev, push to main. This successfully ignored the file in question.
  • Gabriel
    Gabriel about 3 years
    What is the resolution to this?
  • MattSchmatt
    MattSchmatt over 2 years
    @Gabriel: The sad truth is there is no set-and-forget solution as simple as adding a file to a .gitignore afaia. You'd need to use one of the workarounds above (which they are imho) or unfortunately work with other VCSs.
  • liber
    liber over 2 years
    @Brett, In fact, you can keep this file always conflicting on every branch, so you can avoid automatic merging because of there is no conflict. For example, add one line to the file of every branch: <text>{branch_name}</text>