Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Why is git merge from rather than to?

+6
−0

Why does git merge take the source branch rather than the destination branch as a parameter?

The most common merge case by far for me is "Okay, this branch looks good, let's merge it into branch X", where X is often something like master.

Normally, if you're merging, you would expect that some new commits have arrived on the branch recently. If these came from git commit, then obviously you would have the source branch checked out already, which necessitates a clumsy checkout and merge. If these came from git fetch, then you would likewise want to checkout the source branch and see the changes first.

I struggle to think of any use cases for merging from. Why was the merge command designed this way?

History
Why does this post require moderator attention?
You might want to add some details to your flag.
Why should this post be closed?

2 comment threads

Workaround (2 comments)
Educated guess (1 comment)

4 answers

+8
−0

This isn't specific to git merge. The standard Git behaviour is that any content- or history-changing command operates on the current branch. For example, you cannot git commit to a branch other than the current one.[1]

A Git developer would be needed to confirm the canonical reason for this design, but I can think of a couple of likely reasons:

  1. Having a consistent, well-understood interface is generally a good thing. Every developer understands that when they edit a source file, they are making changes to the current working copy, not to some other copy on a different branch. It is therefore easy to understand that VCS commands also write their changes into the current branch or working copy.
  2. Many (perhaps all) changes to content involve using a local staging area called the Git Index, and there is only a single index which reflects changes to the current checked out branch. There is no concept of "the index for branch X".
  3. Many commands (especially merge) can fail, and require the user to resolve conflicts by editing text and committing it. This requires the checked out files to reflect what is about to be committed so that the user can make the necessary edits. It's not clear how editing before commit would work if the destination of the merge wasn't actually checked out to begin with; perhaps the merge would have to simply fail with an error.

None of these issues would be dealbreakers if there was a genuine need for a "merge to" feature, but if the only benefit of such a feature is saving a couple of command-line branch switch operations, it's probably not worth the development time.


  1. It is possible to delete a non-checked-out branch using git branch -d, but deleting a branch doesn't actually delete any commits, it just removes the reference to the branch HEAD so that a subsequent garbage collection can clean up the unreferenced commits. Besides, deleting the checked-out branch would probably leave the working copy in a weird state, so this has to operate on a different branch. ↩︎

History
Why does this post require moderator attention?
You might want to add some details to your flag.

0 comment threads

+6
−0

I can't speak for the people who designed it, but I guess it was made this way because you can merge multiple branches all at once.

Let's say I've created multiple branches:

       C---D   =>  b1
      /    
     /  E---F  =>  b2
     | /   
  A--B--G--H   =>  master
     \
      I---J    =>  b3

And I want to merge branches b1, b2 and b3 onto master. All I need to do is:

git checkout master
git merge b1 b2 b3

As long as there are no conflicts, all will be merged.

Of course I could merge one by one (first git merge b1, then git merge b2 etc), but in this case, each merge will create another commit. If I merge all in one single command, only one commit will be created. Something like this:

       C-------D
      /        |
     /  E---F  |
     | /     \ |
  A--B--G--H---K  =>  master
     \         |
      I--------J

In this case, commit K will have four parent commits: D, F, H and J.

If the command was designed the opposite way, there would be no way to merge all at once. Well, maybe they could add a command line option to include more sources, but that would be confusing IMO. I think the current way is more clear and straightforward: you provide a list of source branches, and they'll all be merged onto the current branch.

I admit, though, this is not a common case, at least in my experience. I myself rarely needed to merge two or more source branches at the same time. But the functionality exists, and is a good reason to keep the command this way, IMO.

But as I said, I can't tell for sure (only guess) if this was the reason to design the command this way. Maybe it was the other way around: first they decided that the current branch is the destination (because that would follow a general design principle), and then realized that the command could be improved to merge multiple branches. Who knows?

History
Why does this post require moderator attention?
You might want to add some details to your flag.

0 comment threads

+4
−0

Another reason could be to allow to perform the merge without auto commit and no fast-forward:

git merge the_branch --no-commit --no-ff

This allows reviewing the merged changes before they are committed.

History
Why does this post require moderator attention?
You might want to add some details to your flag.

0 comment threads

+2
−0

I struggle to think of any use cases for merging from. Why was the merge command designed this way?

The model here is that many developers on the same project are using branches to develop features independently; someone has to be in charge, and that is the person responsible for the master (release) branch that will be used to tag, package and distribute releases of the software. From that person's perspective, merges are naturally into the same branch, which is practically always the destination. It's the source that needs to be specified, because it's the source that varies.

History
Why does this post require moderator attention?
You might want to add some details to your flag.

1 comment thread

Wouldn't that person still need to check out the feature branch first, before merging it? I would exp... (1 comment)

Sign up to answer this question »