0

I'm very new to Git, and I'm trying to understand the workflow of it. I've come to a situation where I don't know how to accomplish what I want to do, and would be glad for someone to explain WHAT is happening and more importantly WHY.

The scenario is this: I'm working on a project with another person. The project consists of different independent sub-projects. The idea is that we will work on the different sub-projects on our own and gradually add the results of these sub-projects into the main project.

To manage this we've created a shared repository on GitHub containing information A. We both clone that repository to out local computers. I locally create a new branch for working on sub-project B and he does the same for sub-project C. In the end we want only one branch on GitHub containing all the information A+B+C.

What are the different ways to accomplish this? The thing I can't get my head around is how I can push my work B into GitHub without making any changes (like removing) his work C that he has already put there. What happens if he locally merges A and C into A+C, pushes that to GitHub, and I then do the same for A+B; what happens then to the C on GitHub? Is it better to find a way to push our separate branches for B and C onto GitHub, and there merge A, B and C into A+B+C?

As you can tell I'm a bit confused by this, and would appreciate some help.

darksmurf
  • 3,747
  • 6
  • 22
  • 38
  • The way you avoid the specific concern you're having is to always `git pull` before performing a merge. Regardless, if you forget to do that, the remote will reject your push, and you'll have to `git reset --hard` your changes, and do them again (or screw your partner over and `git push --force`, which will forcibly override their changes) – Madara's Ghost Apr 19 '15 at 12:37

1 Answers1

2

You should first understand how branching is done in Git. Git doesn't really have a concept of branching like you might think of it. A Git "branch" is actually just a pointer to a commit.

The "branch" you think about, is actually implemented by chaining the top commit (called the branch's HEAD, where the branch pointer points), all the way down to the initial commit.

When you merge two branches, Git will perform a three-way merge of the two branch heads, and create a new commit on the branch you're merging into, with the changes from the branch you're merging.

There are 3 cases:

  • All of the commits in branch to-merge are already in branch merge-into (that happens when you create a branch to-merge, make a few commits, and merge to merge-into without merge-into getting any new commits). In this case, Git will perform a fast-forward (by default), which means that no new commits will be introduced, but the merge-into pointer will simply be forwarded to where the to-merge pointer is. Resulting in all of the commits in to-merge to now be on merge-into as well. You can override this option with the git merge --no-ff flag.
  • Both branches had commits, but none of the changes in branch to-merge overlap with the changes in branch merge-into, in this case, Git will create a new commit with the merge result of both branches. No hassle, no problems.
  • Both branches had commits, and some of the changes overlap. In this case, Git will reject the merge, and will ask you to resolve conflicts. Git will mark conflicts in your files with a special marker, and will ask you to git add the file when you're done, and commit to complete the merge.

So in your case, what I suspect will happen is:

  1. Branch A is not under development. You create branches B and C from it.
  2. Branch B has work you want to merge back into A. Perform git pull origin A to get latest changes (always do that before merging!!!) and then git checkout A; git merge B. What's likely to happen is a fast forward, since A didn't receive any commits.
  3. Branch C now has work you want to merge back into A. Perform git pull origin A to get latest changes (always do that before merging!!!) and then git checkout A; git merge C. What's going to happen is either a new commit is made with the merge (which you can git push origin A back to the remote), or it will tell you that you have conflicts you need to resolve. In which case, resolve, git add the files, then commit and push.

Read More

Madara's Ghost
  • 172,118
  • 50
  • 264
  • 308
  • *Git will perform a three-way merge of the two branch HEADs*. Using a lowercase "head" is preferable here. The uppercase `HEAD` usually refers to the symbolic reference acting as a "you are here" sign, rather than to the tip of a branch. – jub0bs Apr 19 '15 at 13:06
  • 1
    @Jubobs Thanks, edited. (Next time, feel free to perform the edit yourself. Worst case, I'll rollback ;) – Madara's Ghost Apr 19 '15 at 13:07