59

I have two branches, A and B. Branch A have a directory examples with some files that are tracked by git, and these files should not appear on branch B. In my workflow, I do merge changes made in A into B often, which is a problem every time that there is some changes on examples. For the moment I am doing this manually: erasing the files after the merge or solving conflicts when there was a change to a file that I had already erased.

Is it possible to ignore these files during a merge? (Or is it possible to keep some files restricted to one branch (A) or away from one branch (B)?)


Let me try to explain why I am doing this: A is a skeleton of a blog (template, scripts, etc), B is my blog (A filled with my own posts, images, drafts, etc). A is public and I am trying to make it generic to others look and use it, but because of this I need some posts there as a showcase/tests (the examples directory). Every change in A and is later merged into B to have this changes on my blog instance -- this way all new examples appear in B and all deleted examples in B that have been changed in A since last merge results in a conflict.

dbarbosa
  • 2,741
  • 5
  • 23
  • 29
  • It seems that there is something wrong in your workflow. Have you thought of using git submodules instead ? – mb14 Oct 06 '10 at 13:02
  • I have edited my question explaining why I am doing this. I have no experience with submodules. Is it suitable for this? – dbarbosa Oct 07 '10 at 16:33
  • Actually, @Lestat, etc. This is definitely not a duplicate of #928646, because that question regards "conflicted merges", whereas here "all merges" are meant. In this case, no merge drivers are called, and that cuts out the recommended way of handling file differences when there are conflicts: namely using merge drivers. Could this question be unduplicated? – Ron Wertlen Jul 01 '16 at 14:14

3 Answers3

55

I found a good answer here: stackoverflow Q332528

It uses ideas taken from here: Pro-Git merge strategies

Here is a copy of it:

Let's say you want to exclude the file config.php

On branch A:

  1. Create a file named '.gitattributes' in the same dir, with this line: config.php merge=ours. This tells git what strategy to use when mergin the file. In this case it always keep your version, ie. the version on the branch you are merging into.

  2. Add the .gitattributes file and commit

On branch B: repeat steps 1-2

Try merging now. Your file should be left untouched.


Edit:
From the git book regarding merge=ours, "One very useful option is to tell Git to not try to merge specific files when they have conflicts, but rather to use your side of the merge over someone else’s."

So, this answer doesn't apply as well as it might to the question. pjmorse's answer regarding using submodules is good.

Another option would be to use a sub-tree merge, which may have added benefits.

thoni56
  • 2,564
  • 1
  • 22
  • 42
David
  • 3,815
  • 21
  • 33
  • 4
    This didn't work for me, whether I put the myfile merge=ours line in .gitattributes or .git/info/attributes. As I understand it there's no merge conflict between a new file and no file, so there's no strategy issue: when I merge, the file I want excluded appears as "new file: myfile" in "Changes to be committed". – skierpage Jun 19 '12 at 04:04
  • 2
    Right, this only works if you already have your own version of the file(s) committed. I've edited and added some info. – David Jun 19 '12 at 15:13
  • 3
    There s a updated [article](https://git-scm.com/book/uz/v2/Customizing-Git-Git-Attributes) that states you ll also have to declare the merge strategy ours via `$ git config --global merge.ours.driver true` – dag Oct 28 '16 at 06:45
  • @David Thanks! To others reading this answer, don't put a period after "ours" like you see in the answer. – Robert Oschler Aug 06 '17 at 21:20
  • @dag The point you raised was necessary for this to work for me. Thank you for pointing this out. – rotarydial Aug 10 '17 at 05:08
3

You might find git's rerere command useful. With that you can record resolutions for certain merge conflicts and reuse them later.

rafl
  • 11,160
  • 1
  • 49
  • 73
  • 2
    I have tried to follow this: http://progit.org/2010/03/08/rerere.html But it is not working... After the conflict, `git rerere status` and `git rerere diff` doesn't show anything. I have already checked and it is in my ~/.gitconfig, I've created the directory .git/rr-cache in my repository... Anyway, I can see that this will work for the case of changing files in `examples` on `A`. Can this also work for new files?? (if a new file is created in `examples` the merge for this file will not conflict - the file will be added to `B`). – dbarbosa Oct 07 '10 at 17:55
2

With your updates: Yes, submodules would be appropriate for this use if all of A fits in a subdirectory of B (or vice versa). An example of submodules using WordPress would be if you have a git repository of Wordpress; you could add a submodule for a theme which would be inside the /wp-content/themes/ directory.

The documentation for submodules might help.

If the files from the two are interleaved, it might be tougher. Most cases where submodules can be used in this way, the application in question was designed to allow for them.

pjmorse
  • 8,754
  • 9
  • 52
  • 115