Git - Ignore files during merge
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.
-
Add a
.gitattributes
file at the root level of the repository -
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
-
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:
- You have two branches:
master
,develop
- 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
Related videos on Youtube
Kevin Rave
Updated on March 04, 2022Comments
-
Kevin Rave over 2 years
I have a repo called
myrepo
on the remotebeanstalk
server.I cloned it to my local machine. Created two additional branches:
staging
anddev
. 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 over 11 yearsIn 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 over 11 yearsWell, I would say, its checkout. Not pull. I will update the question to be clear.
-
givanse over 10 yearspossible duplicate of Git: ignore some files during a merge (keep some files restricted to one branch)
-
pvinis almost 8 yearsdid 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 over 6 yearsdid you look into symbolic (not followed by git) or even hard links to the rescue?
-
-
Kevin Rave over 11 yearsDoes
git attributes
offer any straight solution? I am not able to understand this. git-scm.com/book/en/… -
Kevin Rave over 11 yearsI 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 over 11 yearsI have not heard of these, I'm trying to apply the merge=ours attribute, looks promising.
-
tlehman over 11 yearsGit attributes are awesome! You can even tell git how to diff non-text files, so you could use pdf2text to diff PDFs!
-
Nate- almost 11 yearsbut I found this git-scm.com/book/ch7-2.html#Merge-Strategies
-
Ilia Shakitko about 7 yearsI'd add "--no-ff" if you want a file not be overwritten when merge happens in fast-forward strategy.
-
Rolf over 6 yearsThat's nice when pushing but still complains when pulling might overwrite the file.
-
Sireesh Yarlagadda over 6 yearshave you tried to add your file entry in .gitignore file. @Rolf
-
Adrian Laurenzi over 6 yearsHere is the correct link for the merge strategies section of the git attributes docs: git-scm.com/book/en/v2/…
-
ShawnFeatherly over 6 yearsFound this well explained in an article medium.com/@porteneuve/…
-
Igor Yalovoy about 6 yearsBut what if there is no conflict? How to always keep a certain file during merge?
-
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 themerge.ours.driver
setting. So you are correct to be concerned. -
Brett almost 6 yearsThis seems to be a problem if there are no conflicts? Files will still be merged?
-
kyb almost 6 yearscopy-paste from Git Docs: Merge Strategies - Git attributes. Link
-
rsmets over 5 yearsThis method results in "merge commits" every time FYI.
-
Kid_Learning_C almost 5 yearsso what does
git reset HEAD myfile.txt
do exactly? How does it help with our goal here? -
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
, thengit config --global merge.foo.driver true
, and it will work the same way. -
Johann over 4 yearsHow do you put lines 2 and 3 in a loop?
-
Zhasulan Berdibekov over 3 yearsThis is working only in situation where have a conflict!
-
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 over 3 years@Kid_Learning_C :
git reset HEAD myfile.txt
unstages the file (which was staged post--no-commit
merging) -
ericOnline about 3 yearsAdding a
.gitattributes
file to themain
branch with<filename-to-exclude> merge=ours
, then runninggit config --global merge.ours.driver true
worked great. The config file indev
was not merged into the config file inmain
. Unfortunately, during the merge the.gitattributes
file was deleted (because it did not exist indev
)! How do avoid this? Just add the same.gitattributes
file todev
? Would theours
value cause a conflict? -
ericOnline about 3 yearsEnded up: Created
.gitattributes
indev
branch according to above comment, add, commit, push todev
. Checkoutmain
,git merge dev
, push tomain
. This successfully ignored the file in question. -
Gabriel about 3 yearsWhat is the resolution to this?
-
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 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>