Setting Up Remote Git Repository and Fetch / Pull - 2020
In this chapter, we'll setup remote git repository and play with local repository
To setup the remote git repo:
$ ssh account@bogotobogo.com ... $ mkdir MyProject.git $ cd MyProject.git $ git --bare init
Here is the structure of the git we've just made:
$ tree -a
Now, we'll set up two git repos at local machines, A and B. A will be connected to remote repo via git remote add while B will be cloned from remote repo via git clone.
On local machine (A):
$ mkdir MyProject $ cd MyProject $ echo "file1" > file1 $ git init $ git add *
$ tree -a
To check current status:
$ git status # On branch master # # Initial commit # # Changes to be committed: # (use "git rm --cached..." to unstage) # # new file: file1 #
If we commit the change:
$ git commit -m "My initial commit message" [master (root-commit) 1c96ab9] My initial commit message 1 file changed, 1 insertion(+) create mode 100644 file1 $ git status # On branch master nothing to commit, working directory clean
Note that the change is limited to local. Now, we may want to make the change to the remote.
The git is a distributed version control system. Most operations are limited to local. To communicate with the outside world, git uses what is called remote. It is a repository other than the one on our local machine which we can push our changes into (so that other people can see them) or pull from (so that we can get others changes).
$ git remote add origin account@bogotobogo.com:MyProject.git
We just created an entry in our git config that specifies a name for a particular URL via git remote add. Note that we must have an existing git repo to use this. As we'll see later, unlike the git remote add, the git clone creates a new git repository by copying an existing one located at the URI we specify.
To share the commit we've done, we need to push our changes to the remote repository. To do this, we run git push [alias] [branch] which will attempt to make our [branch] the new [branch] on the [alias] remote.
Since we've already setup the remote alias via git remote add origin URI, in our push command, we can just push to origin instead of typing out the whole URI.
Let's try it by initially pushing our master branch to the new origin remote we created earlier:
The syntax is:
git push [<remoteName> <branchName>]
The actual command looks like this:
$ git push origin master $ tree -a
The git push origin master command says "push the commits in the local branch named master to the remote named origin". Once this is executed, all the stuff that we last synchronised with origin will be sent to the remote repository and other people will be able to see them there.
The changes been made to the remote repository by the push command is shown in the picture below:
$ tree -a
Now, another team member can share the file1 by cloning the master branch of the remote repository at local B:
$ git clone account@bogotobogo.com:MyProject.git $ cd MyProject $ ls file1
To see which remote servers we have configured, we can run the git remote command. It lists the aliases of each remote handle we've specified. If we've cloned our repository, we should at least see origin - that is the default name Git gives to the server we cloned from.
$ git remote -v origin account@bogotobogo.com:MyProject.git (fetch) origin account@bogotobogo.com:MyProject.git (push)
Another team member at local (B) updates the remote using push:
$ echo "file2" > file2 $ git add file2 $ git commit -m "file2 commit" $ git push origin master
Now, I (at local A) can get the updates using pull:
$ git pull origin account@bogotobogo.com's password: You asked to pull from the remote 'origin', but did not specify a branch. Because this is not the default configured remote for your current branch, you must specify a branch on the command line. $ git pull origin master account@bogotobogo.com's password: From bogotobogo.com:MyProject * branch master -> FETCH_HEAD Updating 1c96ab9..fb8483b Fast-forward file2 | 1 + 1 file changed, 1 insertion(+) create mode 100644 file2 $ ls file1 file2
A fetch command does not make any changes to local branches, so we will need to merge a remote branch with a paired local branch to incorporate newly fetch changes. In other words, the fetch alone cannot do update. We need to use merge command as well as shown below. Suppose, the remote has been updated by adding file3.
$ git fetch origin account@bogotobogo.com's password: remote: Counting objects: 4, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. From bogotobogo.com:MyProject fb8483b..9357619 master -> origin/master $ ls file1 file2 $ git merge origin/master Updating fb8483b..9357619 Fast-forward file3 | 1 + 1 file changed, 1 insertion(+) create mode 100644 file3 $ ls file1 file2 file3
We first ran git fetch origin to tell Git to fetch down all the data it has that we do not, then we ran git merge origin/master to merge into our current branch anything new we see on the server.
Suppose we made a change to a file, file4 at Local A:
$ cat file4 file4 midified by local A
Picture from How do I show the changes which have been staged?.
We can see the difference between the file at the working directory and at the staging area:
$ git diff diff --git a/file4 b/file4 index bfd6a65..ff56b6b 100644 --- a/file4 +++ b/file4 @@ -1 +1,2 @@ file4 +midified by local A
But once we put the file into the staging area, we do not see the difference between working tree and staging area:
$ git add file4 $ git diff
However, we still can see the difference between staging area and HEAD:
$ git diff --cached diff --git a/file4 b/file4 index bfd6a65..ff56b6b 100644 --- a/file4 +++ b/file4 @@ -1 +1,2 @@ file4 +midified by local A
After a commit, we can't see the difference between staging area and HEAD:
$ git commit -m "commit modified file4 by local A" [master 7a6cd63] commit modified file4 by local A 1 file changed, 1 insertion(+) $ git diff --cached
Now we do fecth and merge:
$ git fetch origin $ git merge origin/master Auto-merging file4 CONFLICT (content): Merge conflict in file4 Automatic merge failed; fix conflicts and then commit the result.
In this section we'll see how we can resolve conflicts during fetch, pull, and merge.
If we want to update local B from remote, we do:
$ git fetch origin $ git merge origin/master Updating 25a70af..7a6cd63 Fast-forward file4 | 1 + 1 file changed, 1 insertion(+) $ cat file4 file4 midified by local A
This time, file4 is pushed to the remote by local A:
$ cat file4 file4 midified by local A midified AGAIN by local A
The local B also updated it but from the old file4:
$ cat file4 file4 midified by local A midified by local B git add file4 $ git diff $ git commit -m "commit by local B" [master 3a7a932] commit by local B 1 file changed, 1 insertion(+) git diff HEAD
Now we do fecth and merge:
$ git fetch origin $ git merge origin/master Auto-merging file4 CONFLICT (content): Merge conflict in file4 Automatic merge failed; fix conflicts and then commit the result. $ git diff --cached * Unmerged path file4 $ git diff HEAD diff --git a/file4 b/file4 index 0a86872..19d635a 100644 --- a/file4 +++ b/file4 @@ -1,3 +1,7 @@ file4 midified by local A +<<<<<<< HEAD midified by local B +======= +midified AGAIN by local A +>>>>>>> origin/master
Now that we see the conflicts, we need to updates the file4 from the remote and then modify it.
$ cat file4 file4 midified by local A midified AGAIN by local A $ git merge origin/master error: 'merge' is not possible because you have unmerged files. hint: Fix them up in the work tree, hint: and then use 'git add/rm' as hint: appropriate to mark resolution and make a commit, hint: or use 'git commit -a'. fatal: Exiting because of an unresolved conflict. $ git add file4 $ git commit -m "resolving file4 conflicts local B" [master 389bd9e] resolving file4 conflicts local B $ git merge origin/master Already up-to-date.
Now we can update the file4 and push it to remote:
$ cat file4 file4 midified by local A midified AGAIN by local A midified by local B $ git add file4 $ git commit -m "midified by local B"
As we've done before, the file4 can be pulled from remote to local A:
$ git fetch origin $ git merge origin/master Updating ec81df2..dc017c2 Fast-forward file4 | 1 + 1 file changed, 1 insertion(+)
We can see it's been updated:
$ cat file4 file4 midified by local A midified AGAIN by local A midified by local B
We can use the mergetool such as kdiff3:
Here are the terms used for merging:
- base: name of a temporary file containing the common base for the merge.
- local: name of a temporary file containing the contents of the file on the current branch.
- remote: name of a temporary file containing the contents of the file to be merged.
Git/GitHub Tutorial
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization