Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Always ignore a certain commit on merge in git

I am working on my first project using git and have ran into an issue.

The repo contains a a client/server app. I have a 'master' and 'test' branches, with the intent that master is always the same as what's deployed.

My problem there are 3-4 places in the codebase where the server URL is stored. I want to change this in the 'test' branch, but not in the 'master' branch. The problem is, of course, that whenever I want to merge back to 'master', git wants to put this change in 'master'.

I can do a selective merge and merge all the commits but the one in question, but this seems tedious to do for every single merge. What's the best way to do this?

I've never had this problem in any SCM, so maybe I"m just going about this all wrong.

like image 207
prestomation Avatar asked Nov 04 '22 20:11

prestomation


1 Answers

You want to merge in that change as not being actually merged, but mark it so in history. This way you will know from where to get subsequent changes.

There are a couple of ways to do this. One is

git checkout master
git merge -s ours --no-ff testing
git checkout testing
git merge -s ours --no-ff master

or

git checkout master
git merge testing --no-commit --no-ff
git checkout HEAD -- .
git submodule update # this is optional and only needed if you have submodules
git add -A
git commit
git checkout testing
git merge master --no-commit --no-ff
git checkout HEAD -- .
git submodule update # this is optional and only needed if you have submodules
git add -A
git commmit

Now you have 2 branches with differing configs but those commits are before the important merge-base.

Now you need to script something like this to do the special merge, which is really a rebase underneath -- that's the only way to ignore what happened before:

git checkout master
git merge --no-ff -s ours testing
git checkout -b temp testing
git rebase -s recursive -Xtheirs master # these are the conflicts we care about
git reset --soft HEAD@{2}
git add -A
git submodule update
git commit --amend -C HEAD@{2}
git push . +HEAD:master
git checkout master
git branch -d temp

This just rebases what you don't have on master in branch testing and makes it look like a merge. Because it stores it as a merge, you can subsequently run this against other branches you want to publish to master. So you could separate all those commands with &&s, replace testing with an argument, master with the second argument variables and alias it:

git config alias.smart-merge '...'

so that you can publish changes like so:

git smart-merge testing master
git smart-merge feature2 master

which should give you both testing and feature2 no matter at which point those 2 may have been merged in history already.

Also consider enabling rerere as the script expects no conflicts. So if you do want to publish, you can do a regular rebase first, recording conflict resolutions. Now you can alter the script to take advantage of those and not break on conflicts.

Rebase conflict resolution can be a pain. But not in this case as we only use master to publish. Other branch manipulation is still done via regular merge or rebase.

-- OR --

The non trivial is smudge clean scripts. Take a look at the git attributes chapter in progit.org/book.

Hope this helped.

like image 109
Adam Dymitruk Avatar answered Nov 09 '22 03:11

Adam Dymitruk