This post follows on from the remote repositories post, and deals with two developers collaborating by sharing a remote branch. The next post deals with collaboration via pull requests.
Recall where we are. There are two developers, Alice and Bob. There is a remote repository (they both call it origin
) and each developer has a copy of that shared repository. Look back at the earlier post for details. (The Git book has an excellent section on remote branches. This post is to support that, with some more practical examples).
Adding to an existing branch
Let's say there are two (or more) developers making change to the same branch. This could be when developers are working on features and, when they're finished, want to include them in the master
branch. If Alice makes some changes on master
, Bob will need to update his repo with the changes before including his own.
Let's see how that happens.
Alice makes changes in her local repository
This happens in exactly the same way as usual, covered in part 1 of this guide. She makes changes, saves the changed files, and bundles the changes into a new commit (or series of commits).
alice$ git commit -a -m "Added more text"
alice$ git lg
* 2bb4aa8 - (6 minutes ago) Added more text - Alice (HEAD -> master)
* b8d04bd - (3 days ago) Fancy headings - Neil Smith (origin/master, origin/HEAD)
* 016dfb6 - (4 days ago) Added fourth paragraphs - Neil Smith
* b8d04bd - (4 days ago) Fancy headings - Neil Smith
* 016dfb6 - (4 days ago) Added fourth paragraphs - Neil Smith
* 81bb00e - (4 days ago) Third commit - Neil Smith
* 98690f1 - (4 days ago) Second commit - Neil Smith
* 7c0dffe - (4 days ago) First commit - Neil Smith
(The git lg
command is a custom one I use as a prettier version of git log
. See the earlier post where it's defined. Using git log --oneline
does much the same thing.)
Alice publishes her changes
Alice now needs to tell the world about her changes. The push
command does this.
alice$ git push
alice$ git lg
* 2bb4aa8 - (6 minutes ago) Added more text - Alice (HEAD -> master, origin/master)
* b8d04bd - (3 days ago) Fancy headings - Neil Smith
* 016dfb6 - (4 days ago) Added fourth paragraphs - Neil Smith
* b8d04bd - (4 days ago) Fancy headings - Neil Smith
* 016dfb6 - (4 days ago) Added fourth paragraphs - Neil Smith
* 81bb00e - (4 days ago) Third commit - Neil Smith
* 98690f1 - (4 days ago) Second commit - Neil Smith
* 7c0dffe - (4 days ago) First commit - Neil Smith
You can see that the origin/master
branch has changed.
Bob updates his local repository
The origin
repository has changed, and Bob needs to see what's happened. The git fetch
command does that.
bob$ git fetch
bob$ git lg
* 2bb4aa8 - (6 minutes ago) Added more text - Alice (origin/master, origin/HEAD)
* b8d04bd - (3 days ago) Fancy headings - Neil Smith (HEAD -> master)
* 016dfb6 - (4 days ago) Added fourth paragraphs - Neil Smith
* b8d04bd - (4 days ago) Fancy headings - Neil Smith
* 016dfb6 - (4 days ago) Added fourth paragraphs - Neil Smith
* 81bb00e - (4 days ago) Third commit - Neil Smith
* 98690f1 - (4 days ago) Second commit - Neil Smith
* 7c0dffe - (4 days ago) First commit - Neil Smith
That's told Bob that origin
has changed, but that's still in a different branch from the one he's working on. Bob can now update his version of the master
branch to match the one from origin
. In this case, that's just a fast-forward merge, so a git merge
is all that's needed.
bob$ git merge
bob$ git lg
* 2bb4aa8 - (7 minutes ago) Added more text - Alice (HEAD -> master, origin/master, origin/HEAD)
* 016dfb6 - (4 days ago) Added fourth paragraphs - Neil Smith
* b8d04bd - (4 days ago) Fancy headings - Neil Smith
* 016dfb6 - (4 days ago) Added fourth paragraphs - Neil Smith
* 81bb00e - (4 days ago) Third commit - Neil Smith
* 98690f1 - (4 days ago) Second commit - Neil Smith
* 7c0dffe - (4 days ago) First commit - Neil Smith
The combination offetch
thenmerge
is so common, there's a shortcut command to do them both together:git pull
. But you should note thatpull
includes a fullmerge
, and may lead to you having to deal with a merge conflict. If you're not confident that apull
will be smooth sailing, you shouldgit fetch
rather thangit pull
so you can see what the merge will end up doing.
These two developers can continue in this way quite happily, updating, pushing, and pulling commits on the same branch. But that's not always the best way of working. Sometimes you need new branches.
Publishing a new branch
Branches in your local repository remain local to there until you decide to publish them. You can work in private on a feature, try out different experiments, perhaps even abandon it, and no-one else will be any the wiser.
Alice creates a local branch
As Alice, create a new branch, switch to it, and change all the words of one file to start with a capital letter. Then commit the change.
alice$ git branch mixed-case
alice$ git switch mixed-case
alice$ sed -i -e "s/\b\(.\)/\u\1/g" frankenstein.txt
alice$ git commit -am "Mixed case"
alice$ git lg
* b8a1271 - (89 seconds ago) Mixed case - Alice (HEAD -> mixed-case)
* 2bb4aa8 - (7 minutes ago) Added more text - Alice (origin/master, master)
* 016dfb6 - (4 days ago) Added fourth paragraphs - Neil Smith
…
Alice publishes the new branch
At the moment, this branch is just in Alice's repository. Alice can now push that up to the origin
remote repository
alice$ git push origin mixed-case
To github.com:NeilNjae/git-workshop.git
…
* [new branch] mixed-case -> mixed-case
git lg
* b8a1271 - (2 minutes ago) Mixed case - Alice (HEAD -> mixed-case, origin/mixed-case)
* 2bb4aa8 - (7 minutes ago) Added more text - Alice (origin/master, master)
This shows the creation of the new remote branch, origin/mixed-case
.
Bob gets the branch
Bob can now see that new branch with a git fetch
bob$ git fetch
bob$ git lg
* b8a1271 - (3 minutes ago) Mixed case - Alice (origin/mixed-case)
* 2bb4aa8 - (8 minutes ago) Added more text - Alice (HEAD -> master, origin/master, origin/HEAD)
Bob can start using that branch by switch
ing to it, using the --track
option to tell git to create a new local branch that tracks the remote one.
bob$ git switch --track origin/mixed-case
Branch 'mixed-case' set up to track remote branch 'mixed-case' from 'origin'.
Switched to a new branch 'mixed-case'
bob$ git lg
* b8a1271 - (4 minutes ago) Mixed case - Alice (HEAD -> mixed-case, origin/mixed-case)
* 2bb4aa8 - (9 minutes ago) Added more text - Alice (origin/master, origin/HEAD, master)
Bob writes to the remote branch
Bob can then make some changes in that new branch, commit them, and push the changes.
bob$ sed -i -e "s/\b\(.\)/\u\1/g" carmila.txt
bob$ git commit -am "Fixed carmilla as well"
bob$ git lg
* d42604c - (2 seconds ago) Fixed carmilla as well - Bob (HEAD -> mixed-case)
* b8a1271 - (28 minutes ago) Mixed case - Alice (origin/mixed-case)
* 2bb4aa8 - (33 minutes ago) Added more text - Neil Smith (origin/master, origin/HEAD, master)
…
bob$ git push
bob$ git lg
* d42604c - (2 seconds ago) Fixed carmilla as well - Bob (HEAD -> mixed-case, origin/mixed-case)
* b8a1271 - (28 minutes ago) Mixed case - Alice
* 2bb4aa8 - (33 minutes ago) Added more text - Alice (origin/master, origin/HEAD, master)
…
Alice fetches Bob's changes
Finally, Alice can fetch the changes and merge them (this is a case where git pull
would be more convenient, as Alice hadn't made any changes in her copy of this branch).
alice $git fetch
From github.com:NeilNjae/git-workshop
b8a1271..d42604c mixed-case -> origin/mixed-case
alice$ git lg
* d42604c - (3 minutes ago) Fixed carmilla as well - Bob (origin/mixed-case)
* b8a1271 - (31 minutes ago) Mixed case - Alice (HEAD -> mixed-case)
* 2bb4aa8 - (36 minutes ago) Added more text - Alice (origin/master, master)
alice$ git merge origin/mixed-case
Updating b8a1271..d42604c
Fast-forward
carmila.txt | 36 ++++++++++++++++++------------------
1 file changed, 18 insertions(+), 18 deletions(-)
$ git lg
* d42604c - (5 minutes ago) Fixed carmilla as well - Bob (HEAD -> mixed-case, origin/mixed-case)
* b8a1271 - (33 minutes ago) Mixed case - Alice
* 2bb4aa8 - (38 minutes ago) Added more text - Alice (origin/master, master)
Credit
Photo by Zach Reiner on Unsplash