XiOS XiOS - 21 days ago 10
Git Question

Git update my remote branch from another remote branch

We have a master branch called 'develop', so whenever we develop a feature, we will make a local feature branch from 'develop' and later merge back to develop.

Now a case that,

1. User1 had to make a feature branch from 'develop'(say feature1) and he has to publish it to Git. This is done.

So now, 'develop' and 'feature1' are 2 different branches in Git and changes in 'feature1' are not merged to 'develop' as 'feature1' is still under development.

2. Later the feature that I started implementing had some dependency on 'feature1'. So I cloned the 'feature1' branch from git and decided to update my changes to it, thinking that 'feature1' would have been already updated from 'develop' branch.

3. But later I found that 'feature1' branch is NOT updated with some recent changes from 'develop' branch.

4. Now I need the changes in 'develop' branch to be updated in 'feature1' branch before updating my changes to it.

Any possible way to do this with GIT commands ?

Answer

From what I gathered, this is the situation in your repository:

                  develop
                    ↓
A -- A -- B -- C -- C
           \
            F -- F -- F
                      ↑
                   feature1

So, commits A are commits on develop that existed before. B is the base commit that develop was on when the feature branch was created. F are commits that were made on the feature branch, and C are commits that were made on develop after the feature branch was already created and being worked on.

Now, what you want to do is to continue working on the feature branch, while depending on the changes that were introduced with commits C. Is that right?

In that case, assuming you are not the same developer as user 1, the safest way to introduce those changes into the feature branch is to simply merge them in. So while having feature1 checked out, just merge develop using `git merge develop*. Then, the history will look like this:

                      develop
                         ↓
A -- A -- B ---- C ----- C
           \              \
            F -- F -- F -- M
                           ↑
                        feature1

So you simply merge the changes, and then you can continue working on it. In fact, you can continue doing that multiple times as both feature1 and develop grow:

                                     develop
                                        ↓
A -- A -- B ---- C ----- C -- C -- C -- C
           \              \         \    \
            F -- F -- F -- M -- F -- M -- M -- F
                                               ↑
                                            feature1

And once you’re done with the feature branch, you can just merge it into develop:

                                              develop
                                                 ↓
A -- A -- B ---- C ----- C -- C -- C -- C ------ M
           \              \         \    \      /
            F -- F -- F -- M -- F -- M -- M -- F

Of course, this makes the history look somewhat messy, but it correctly represents how the feature branch evolved over time while relevant changes were still happening on develop.


There are a few alternatives if you want to avoid the history looking like that. If you just depend on very few changes, e.g. some that were introduced in a single commit while the other commits are irrelevant to you, you could also cherry-pick that one commit onto the feature branch. Cherry-picking allows you to copy a commit, essentially reusing it completely while still having it as a separate commit.

Let’s say, you only need the first commit C from the very first graph shown above. Then you could do git cherry-pick C1 to copy it over to the feature branch:

                  develop
                     ↓
A -- A -- B -- C1 -- C2
           \
            F -- F -- F -- C1'
                            ↑
                        feature1

This creates a copy C1' which includes the same changes as its original C1 (but is still a different commit object). You can then continue working on the feature branch with those changes included.


Finally, the remaining alternative would be rebasing. Rebasing rewrites the history, so again starting from the very first graph, you could end up with the following by running git rebase develop:

                 develop
                    ↓
A -- A -- B -- C -- C
                     \
                      F' -- F' -- F'
                                  ↑
                               feature1

The important thing to keep in mind is that the history is really rewritten, so all the commits on feature1 are modified and recreated. This causes them to be completely different objects with a different commit identifier, making them incompatible to the previous state of the branch.

This causes other developers, in your case especially that “user 1” who is working on the feature1 branch as well, to run into conflicts when they try to incorporate your changes. Fixing that will require them to manually fix it, and unless you tell them, they might not even notice (making the history very messy and somewhat broken as a result).

So unless you know what you’re doing, you should never rebase commits that have been published before. Even if that means that your history will look less nice as a result.

Comments