We use github for tracking our code. Each developer creates a remote branch from the main branch and a local branch from the remote branch.
Let's say the main branch is A, the remote branch is B, and the local branch is C.
Let's say a file README has just one line in it:
LineX
At the beginning, this file has the same contents on all three branches.
Let's say I add one line into this file in my local branch.
LineX
LineY
Meanwhile, someone added another line on branch A and committed it.
LineX
LineZ
Here is how the contents would look at that point:
Branch A:
LineX
LineZ
Branch B:
LineX
Branch C:
LineX
LineY
I need to pull the changes from Branch A into C so that my local content would become:
LineX
LineY
LineZ
Also, I feel Branch B must be synced with A. Otherwise, my code review will show two lines of changes instead of one line.
I am wondering what is the proper way to do this. Thanks.
CodePudding user response:
If there is no commit history in branch C when branch A into branch C
$ checkout Branch_A
$ pull Branch_A
$ checkout Branch_C
$ merge Branch_A
branch C becomes as follow like this.
LineX
LineZ
In this case, compare the branches before working (git diff) You need to check which commit was made through the git log.
CodePudding user response:
tl;dr: Instead of syncing B
with A
, you'll be syncing B
with C
, and then doing a Pull Request from B
to A
which will show only the new changes you made on your local branch C
.
Details:
Although you can do this:
We use github for tracking our code. Each developer creates a remote branch from the main branch and a local branch from the remote branch.
the far more common way is to not worry about the remote branch until you are ready to do a code review or Pull Request (i.e. share your code). Each developer initially only needs to think about main
("Branch A" in your example), and their local my-feature
branch ("Branch C" in your example). The local branch is created from the remote main branch.
Let's call your remote origin
. To begin working on something new:
# Get the latest copy of the remote main branch:
git fetch
# Create a new local branch starting from main
git switch -c my-feature origin/main --no-track
# or the older syntax using checkout instead of switch
git checkout -b my-feature origin/main --no-track
At this point my-feature
will be equivalent to the remote version of main
. Note you don't even need to have a local branch main
checked out, possibly ever!
When it's time to update your feature branch with new contents on main
you can either rebase or merge:
# update my-feature from latest main via rebase
git fetch
git rebase origin/main my-feature
# or update my-feature from latest main via merge
git switch my-feature
git fetch
git merge origin/main
Tip: if you have already pushed
my-feature
and then you rebase it, the next push will need to be a force push. This won't be necessary if you merge instead. Your repo admin should be able to provide guidance on whether force pushing feature branches is encouraged/discouraged.
Note it's at this regular updating step (merge or rebase) that you would achieve your example of:
LineX
LineY
LineZ
Since the lines are next to each other you would have conflicts, and during conflict resolution you would accept both lines from each side to yield the desired result. If the lines were in different parts of the file the merge or rebase would like finish cleanly without conflicts.
Once you are ready to create a Pull Request or do a code review, or collaborate with someone so they can see your branch, you need to push your branch to create its remote counterpart ("Branch B" in your example).
# the first time you push, set up to track it
git push -u origin my-feature
# any subsequent pushes:
git push
Note the PR gets setup on GitHub from my-feature
to main
. From a developer's (recently fetched) local machine, this is equivalent to origin/my-feature
to origin/main
, or in your example, PR'ing B
into A
. Developers typically make their changes on their local branch C
and continuously update its remote tracking branch B
by pushing.
Side Note: The wording of your first paragraph kind of implies that you already have this process setup and have been using it. If you want to avoid changing that process it's fine, as it's compatible with the rest of what's described in this answer. The initial creation of the remote branch doesn't really hurt anything. Although unconventional, if nothing else its existence could signal to other developers that you started working on something. The only difference would be instead of creating a new local branch from origin/main
, you would instead:
# on Github, create my-feature from main, and then locally:
git fetch
# checkout a local copy of my-feature
git switch my-feature
# or the older syntax using checkout instead of switch
git checkout my-feature
Everything else would be the same as above, except you wouldn't need to set up the remote tracking branch with push -u
. You would simply use git push
to update your branch. (Or, git push --force-with-lease
if you're rebasing onto a newer origin/main
.)