1

I am trying to understand what is the process for testing two versions of the code while making changes to common code that is identical across versions. I want to have branch-specific code that is not affected when I merge, and common code that is merged whenever I make changes in either branch.

Here is a testcase:

branch 1:

commoncode line
branch1 specific code

branch2:

commoncode line
branch2 specific code

suppose I am working on branch 1, and I make changes to the commoncode that should propagate to branch 2 when merging. When I checkout branch 2 instead, and I git merge branch1 both lines are changed without raising a conflict. What I would like is for the specific code to remain the same (and the common code to merge), or at least raise a conflict.

What is a workable process to achieve something like this?

2
  • Git's got somewhere between a boatload and an entire fleet of tools to do this in whatever way you want. This is what HEAD and the index are for. git reset with or without -p, git add with or without -p, git checkout -m, git commit -o, these are all about constructing multiple new commits from what's in your work tree and recording them on whatever tip is needed. Commented May 10 at 23:26
  • Thanks. I am glad it's possible, but it would be nice to get some reference as to how to do it. This seems like a very common scenario, I'm surprised I can't find any help on this. Commented May 11 at 15:14

4 Answers 4

1

your main question: How can you handle updates to shared code during merges without impacting branch-specific code?

  1. Store shared code in a directory and keep branch specific code in separate directories for each branch.

  2. Use git merge to incorporate changes from the shared code into different branches.

  3. After each merge, thoroughly test the code to ensure that the shared code is updated correctly, while branch-specific code remains unchanged.

good luck mate, Hopefully, this will guide you in the right direction

Sign up to request clarification or add additional context in comments.

Comments

1

I want to have branch-specific code that is not affected when I merge

There are 2 general ways to accomplish this:

  1. Use a custom merge script which "knows" which files and/or parts of files should be ignored. (Tip: ignoring complete files is easier than ignoring portions of files.) The idea here is that the script starts the merge with: git merge --no-commit. Then it undoes changes to certain files (or portions of files), then it completes the merge. The downside of this is you must know what all of the stuff to ignore is in advance.
  2. Use n+1 branches. In your case, if you have two branches with stuff on it, say branch1 and branch2, then you need a third branch with all the common code, say, main. Make common changes to main, and then merge main into both branch1 and branch2 when you're ready to take those changes. Then, only put branch1 specific code in branch1, and similarly only put branch2 specific code in branch2, and never merge branch1 into branch2, or vice versa.

3 Comments

#2 is the first approach that works for me, in part, among all that have been suggested. The problem is if I make changes to common code in either branch1 or branch2, and merge them into common, they're eventually going to propagate branch specific code to the wrong branch
@andream. that's correct. This method is a general guideline, and it does require some thinking ahead about what will end up being "common code", thus the last sentence: "Then, only put branch1 specific code in branch1, and similarly only put branch2 specific code in branch2". If you follow that you should never merge branch1 or branch2 into common. Of course we can't always be perfect (or we may change our mind), and if you decide later you want to make some portions of commits from branch1 common code, there are ways to achieve that. Some ideas.
@andream. Side note, if you have made changes on branch1 but haven't committed yet, and you now realize that some of the changes should go to common instead, then use jthill's answer to stage specific hunks and only commit those that are not common code.
1

Do the work in your work tree, record it where it belongs. Git is made for this.

Here's the basic sketch

git checkout branch1
work work work making common and branch1 changes but not adding anything yet
git commit -p                  # pick only the branch1-specific changes
git checkout -m common         # now carry any remaining changes over to the common tip
git commit -a                  # add and commit those
git checkout branch2           # then merge them in to the branch2 tip
git merge common               # ...

and if your tip-specific changes are in separate files you can skip the patch selection with git commit -o instead of git commit -p.

4 Comments

I don't know what's wrong, but after git checkout -m common I get no special feedback (Switched to branch 'common', but then if I do git merge branch1 it complete overwrites common with branch1 code
? nowhere in the sequence I gave is there a git merge branch1, did you do the git commit -a?
When I do git commit -a it says: On branch common nothing to commit, working tree clean The problem is that in the checkout -m common the -m doesn't do anything
If git commit -a doesn't do anything then you have no changes to tracked files in your work tree. Which means you didn't do the "work work making changes but not adding anything yet" step.
-2

You’re asking about a Git workflow where you want to merge common code changes while keeping the branch-specific code intact. Here’s a process you can follow to achieve that:

1. Use git merge for the common code

When you are working on a feature in branch 1, and you want to modify common code, follow these steps:

  1. Make the common code change in branch 1.
  2. Commit the change to branch 1.
  3. When you switch to branch 2, you can use git merge branch1 to pull the common code changes into branch 2.

Git will automatically merge the common code. However, it won’t touch the specific code in branch 2 because it has different changes.

2. Prevent automatic merging of specific code

To prevent Git from automatically merging the specific code and instead raise a conflict or leave it unchanged:

  1. Use git merge with -X ours or -X theirs to prefer one branch's changes.

    • git merge branch1 -X ours: This keeps your changes in branch 2 and ignores the changes from branch 1 for specific code.
    • git merge branch1 -X theirs: This does the opposite, where the changes from branch 1 are preferred for the specific code in branch 2.

    If you do a regular git merge, Git will try to merge everything, including the branch-specific code. But with -X ours or -X theirs, you’re telling Git to prioritize one side for specific code.

3. Use Git's Conflict Resolution Process

If you want a conflict to be raised for the specific code, you can manually edit the code to introduce a conflict before merging. For example, in branch 2, you can temporarily modify the specific code in a way that will cause a conflict when merged, and Git will then prompt you to resolve it.

Alternatively, if you're working with rebase instead of merge:

  1. Rebase your changes onto the other branch, and Git will preserve changes in branch 2 but still bring in the common code changes.
  2. During rebase, if there’s a conflict, Git will stop and let you resolve it.

4. Branch-Specific Code in Separate Files/Methods

If feasible, consider isolating branch-specific code into separate files or methods that won’t overlap with the common code. That way, merging becomes easier because there’s a clearer distinction between the common code and the branch-specific code.

Example Workflow:

  1. Make your changes in branch 1.
  2. Commit those changes.
  3. Switch to branch 2 and merge branch1 with a strategy (-X theirs, -X ours), or manually resolve the conflict if you want to be more explicit.
  4. Test the result and push.

That’s a clean way to ensure that common code merges while keeping branch-specific code intact.

Let me know if you need more clarification!

4 Comments

It does not seem to work. When I use -X theirs all lines are overwritten with the merging branch content. With -X ours with the merged branch.
Ah I missed your point #4. Is the use of separate files really the only way?
"git merge branch1 -X ours: This keeps your changes in branch 2 and ignores the changes from branch 1 for specific code." No. That's not what -X does. -X will take all branch1 code, except for the lines that have conflicts, in which case it will take branch2 code for only those lines.
Oops my bad @TTT

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.