This git clone tutorial shows how to collaborate on github
Command: git clone: Clones a repository into a new directory
Usage of git clone command:
--git clone repository git clone <repo> git clone <repo> <directory>
There is repo to repo collaboration, and no central repository:
NOTE: If no <directory> name is given, a directory will be created with the same name as the remote repository.
<repo_url> can be of any protocol types as: https, http, ssh, remote server, local path git URLs also supports ftp but it is deprecated.
b) Clone different repositories
#https: git clone https://github.com/projectA/submodule #http: git clone http://github.com/projectA/submodule #ssh: git clone ssh://firstname.lastname@example.org/path/to/repo/myProject.git #Clone from a remote server: git clone email@example.com:/home/divya/gitRepos/initialRepo.git #Clone from your local path: git clone file:///local/path
There is also a –-bare flag to the ‘git clone’ command that creates a bare repository to publish your changes. We shall cover this in detail under the ‘bare repository’ section.
visualize and add/rename/delete remote refs
“remotes” refer to remote connections to other repos.
It’s a shortname for a long url or references to a commit, such as a branch, tag, HEAD, remote branch.
Step 1: Clone the project
Under your home directory, run the below git clone command:
git clone http://github.com/divyabhushan/learnRemotes.git learnRemotes
A new directory ‘learnRemotes’ will be created, this is your working directory
Cloning into 'learnRemotes'... warning: redirecting to http://github.com/divyabhushan/learnRemotes.git/ remote: Enumerating objects: 27, done. remote: Total 27 (delta 0), reused 0 (delta 0), pack-reused 27 Unpacking objects: 100% (27/27), done.
Step 2: show remote repos
List the remote repository for this local working directory:
$git remote origin
Step 3: verbose and show remote url
--List the url of the remote repo $git remote -v origin http://github.com/divyabhushan/learnRemotes.git (fetch) origin http://github.com/divyabhushan/learnRemotes.git (push)
‘origin’ is the default remote name assigned by the ‘git clone’ command.
This remote reference gives both ‘fetch’ and ‘push’ access to the cloned working directory.
Step 4: Add remote repositories
--add another remote reference ‘origin2’ to the same commit git remote add origin2 http://github.com/divyabhushan/learnRemotes.git --add a remote reference ‘myProj’ to a different local repository git remote add myProj ~/OneDrive/gitRepos/myProj --List the remotes git remote -v
NOTE: Other url protocols such as ‘https’, ‘ssh’, ‘file:///…’ etc can also be used to add remotes.
myProj /Users/Divya1/OneDrive/gitRepos/myProj (fetch) myProj /Users/Divya1/OneDrive/gitRepos/myProj (push) origin http://github.com/divyabhushan/learnRemotes.git (fetch) origin http://github.com/divyabhushan/learnRemotes.git (push) origin2 http://github.com/divyabhushan/learnRemotes.git (fetch) origin2 http://github.com/divyabhushan/learnRemotes.git (push)
NOTE: Both ‘origin’ and ‘origin2’ points to the same remote url.
Step 5: Rename a remote name
git remote rename <old-name> <new-name>
git remote rename myProj LocalRepo_myProj --list the remotes git remote
LocalRepo_myProj --renamed origin origin2
Step 6: Remove a remote repository reference
This will only remove the remote reference to the repo.
--remove the duplicate reference to ‘origin’ repo git remote remove origin2 --List the remotes git remote
( git remote -r, git branch --track, --set-upstream-to)
Step 7: List the remote branches
‘git clone’ checks out just the active checked out branch on the remote server.
Let’s have a look at the remote branches:
git branch --remote OR git branch -r
origin/B1 origin/dev origin/localB1 origin/master origin/prod origin/remoteB2 origin/uat
Step 8: List the local branches tracking remote branches
$git branch -vv * dev e422743 [origin/dev] Merge branch 'localB1' master d45cfd6 [origin/master] another edit from master newBranch 61435ed Adding the author
NOTE: Local branch ‘master’ already set to track ‘origin/master’ when we cloned the repository.
Git clone branch: To clone a remote branch use the ‘git checkout <remote/branch_name>
Checkout a remote branch as a local branch with the --track flag; that sets local branch to track remote branch with the same name.
$ git checkout --track origin/dev Branch 'dev' set up to track remote branch 'dev' from 'origin'. Switched to a new branch 'dev'
You could also switch to the newly created branch while checking it out with the --track flag.
$git checkout --track -b uat origin/uat Branch 'uat' set up to track remote branch 'uat' from 'origin'.
NOTE: The command will fail if a local branch with the same name (‘uat’) already exists.
$--verbose mode of branch listing git branch -vv * uat 37d931b [origin/uat] local branch1 notes added
Step 9: Manually set the local branch to track the remote(upstream) branch
Create a new branch ‘dev2’ and set it to track the same remote branch ‘origin/dev’
git checkout -b dev2 --list the branches in verbose mode: git branch -vv
dev e422743 [origin/dev] Merge branch 'localB1' * dev2 e422743 Merge branch 'localB1' master d45cfd6 [origin/master] another edit from master
--Add upstream information for the current active branch git branch --set-upstream-to=origin/dev Branch 'dev2' set up to track remote branch 'dev' from 'origin'.
--List the local branch and upstream branch relationship $git branch -vv dev e422743 [origin/dev] Merge branch 'localB1' * dev2 e422743 [origin/dev] Merge branch 'localB1' master d45cfd6 [origin/master] another edit from master
NOTE: Both local branches ‘dev’ and ‘dev2’ tracking the same upstream remote branch ‘origin/dev’
Any changes in the remote branch will be tracked by the local branches and ‘git status’ will show you the changes.
Step 10: Add upstream information for other local branches; that are not currently checked out.
git branch --set-upstream-to=origin/master master Branch 'master' set up to track remote branch 'master' from 'origin'.
Step 11: To unset/remove the upstream tracking for local branch.
--Remove upstream information for the default checked out branch git branch --unset-upstream-to --Remove upstream information for other branch git branch --unset-upstream-to master
a) ‘git fetch’ to update references
‘git fetch’ command downloads objects and refs from another(remote) repository.
It updates the references to the remote repo.
This does not affect the working directory, unless you do a ‘merge’.
--Fetch from default origin git fetch --Fetch from origin git fetch origin --Fetch from another remote repository git fetch myProj --Fetch from all remotes git fetch –all --Show details git fetch --verbose --Fetch all tags from the remote git fetch --tags
git fetch origin warning: redirecting to https://github.com/divyabhushan/learnRemotes.git/ From http://github.com/divyabhushan/learnRemotes = [up to date] master -> origin/master = [up to date] B1 -> origin/B1 = [up to date] dev -> origin/dev = [up to date] localB1 -> origin/localB1 = [up to date] prod -> origin/prod = [up to date] remoteB2 -> origin/remoteB2 = [up to date] uat -> origin/uat
--List of remote branches after the ‘fetch’ command git branch -r origin/master origin/B1 origin/dev origin/localB1 origin/prod origin/remoteB2 origin/uat
We now have a reference to remote branches from our local repository.
To work on a remote branch, simply checkout that branch on your local repo working directory:
git checkout dev Branch 'dev' set up to track remote branch 'dev' from 'origin'. Switched to a new branch 'dev'
NOTE: ‘git fetch’ uses the ‘--dry-run’ flag to review what remote references are going to be downloaded without actually doing so:
git fetch --dry-run <remote_name> example: git fetch --dry-run origin
Any new branches added to the remote repository will not be reflected in your local repository, unless you explicitly refresh your tracking list using:
‘git fetch <remoteName>’
‘git fetch’ facilitates the removal of stale references to remote repository from your local repository.
--List remote branch git branch -r origin/uat git branch -vv * uat a109623 [origin/uat] add version:1.0
git fetch alone will not remove the local references.
Run ‘git fetch’ with the --dry-run flag:
--Review what is going to pruned git fetch --prune --dry-run origin From /Users/Divya1/OneDrive/gitRepos/test/remoteRepo - [deleted] (none) -> origin/uat
--Fetch origin git fetch --prune origin From /Users/Divya1/OneDrive/gitRepos/test/remoteRepo - [deleted] (none) -> origin/uat
--Remote reference to origin/uat now removed git branch -r git branch -vv * uat a109623 [origin/uat: gone] add version:1.0
Alternatively, ‘git remote prune’ command also prunes the references
git remote prune origin --dry-run Pruning origin URL: /Users/Divya1/OneDrive/gitRepos/test/remoteRepo/ * [would prune] origin/uat
Run the above command without the --dry-run flag.
‘git pull’ = ‘git fetch’ + ‘git merge’
Definition from manual page:
“Fetch from and integrate with another repository or a local Branch”
git pull <options> <repository> <refspec> --Pull commits from origin ‘master’ branch into local ‘master’ branch git pull origin master --Merge remote branch ‘dev’ into local branch ‘dev’ git pull origin dev
<refspec>: Is a remote reference, such as a branch or a tag.
--no-commit: Perform the merge but do not autocommit.
--no-ff: Create a merge commit even when the merge resolves as a fast-forward
--allow-unrelated-histories: Allow merges of uncommon ancestry branches
Case 1: Pull changes from “origin/master” into local “master”
Local branch ‘master’ already set to track remote branch ‘origin/master’
To achieve: Synchronize local ‘master’ branch with remote ‘origin/master’
cd learnRemotes git checkout master git reset --hard 0847197 --Show verbose list of local and remote branches git branch -vv
--local ‘master’ behind by 5 commits from ‘origin/master’ * master 0847197 [origin/master: behind 5] Initial import, README added
‘master’ history before a pull from remote
$git hist * 0847197 2015-04-05 | Initial import, README added (HEAD -> master) [divya]
Let us see the 5 commit logs missing in ‘master’
$ git log --oneline master..origin/master d45cfd6 (origin/master) another edit from master dc70e1a Edit from local master e422743 (origin/dev, dev) Merge branch 'localB1' 45c5184 local branch2 notes added 37d931b (origin/uat) local branch1 notes addeda
It’s a good idea to also view the difference and compare the code between the ‘master’ and ‘origin/master’
$ git diff master..origin/master diff --git a/README b/README index c39619d..77a1f6e 100644 --- a/README +++ b/README @@ -1 +1,3 @@ This is a README file +edit from local master W.D. +another edit from local master. diff --git a/branch2.notes b/branch2.notes new file mode 100644 index 0000000..792d600 --- /dev/null +++ b/branch2.notes @@ -0,0 +1 @@ +# diff --git a/localNotes.txt b/localNotes.txt new file mode 100644 index 0000000..792d600 --- /dev/null +++ b/localNotes.txt @@ -0,0 +1 @@ +#
Pull these missing code changes into ‘master’
git pull origin master
From github.com:divyabhushan/learnRemotes * branch master -> FETCH_HEAD Updating 0847197..d45cfd6 Fast-forward README | 2 ++ branch2.notes | 1 + localNotes.txt | 1 + 3 files changed, 4 insertions(+) create mode 100644 branch2.notes create mode 100644 localNotes.txt
‘master’ branch is now in synch with the ‘origin/master’
You could check its commit history, the working directory.
* d45cfd6 2018-08-17 | another edit from master (HEAD -> master, origin/master, origin/HEAD) [divya] * dc70e1a 2018-08-17 | Edit from local master [divya] * e422743 2015-05-10 | Merge branch 'localB1' (origin/dev, localB1, dev) [divya] |\ | * 37d931b 2015-04-05 | local branch1 notes added (origin/uat, uat) [divya] * | 45c5184 2015-04-05 | local branch2 notes added [divya] |/ * 0847197 2015-04-05 | Initial import, README added [divya]
‘git status’ command also prints the local and remote branch status.
On branch master Your branch is up to date with 'origin/master'. nothing to commit, working tree clean
Case 2: Pull from a remote branch into a local branch
Create a “B1” branch from the initial “master” history
git checkout -b B1 0847197
Switched to a new branch 'B1'
Check history of branch ‘B1’
* 0847197 2015-04-05 | Initial import, README added (HEAD -> B1) [divya]
Set “B1” to track “origin/B1” and pull changes from remote
git branch --set-upstream-to=origin/B1 Branch 'B1' set up to track remote branch 'B1' from 'origin'.
Show verbose listing of branches
$git branch -vv * B1 0847197 [origin/B1: behind 2] Initial import, README added
NOTE: local branch ‘B1’ is behind remote branch ‘origin/B1’ by 2 commits.
Pull the remote changes into ‘B1’
--If the local branch is set to track remote branch, run: git pull --If local branch not set to track remote branch, run: git pull <remoteRepo> <remoteBranch>:<localBranch> git pull origin B1:B1
Either ways, the output will be as below:
From github.com:divyabhushan/learnRemotes 0847197..61435ed B1 -> B1 warning: fetch updated the current branch head. fast-forwarding your working tree from commit 08471971aa3522ea722fc2c7f320279e44dc6ada. Already up to date.
Commit history of ‘B1’ will be in sync with the ‘origin/B1’:
* 61435ed 2018-09-26 | Adding the author (HEAD -> B1, origin/B1) [divya] * e870852 2018-09-26 | Adding version:1.0 [divya] * 0847197 2015-04-05 | Initial import, README added [divya]
‘Reset --hard' the commit history of ‘B1’ back to first commit, Un-set the branch tracking between ‘B1’ and ‘origin/B1’ and run the ‘pull’ command
git checkout B1 git branch --unset-upstream git branch -vv
--‘B1’ not tracking ‘origin/B1’ anymore * B1 61435ed Adding the author
‘git pull’ command will fail
There is no tracking information for the current branch. Please specify which branch you want to merge with. See git-pull(1) for details. git pull <remote> <branch> If you wish to set tracking information for this branch you can do so with: git branch --set-upstream-to=<remote>/<branch> B1
Solution 1: Set the branch tracking again, and run ‘git pull’
Solution 2: run ‘git pull origin B1:<localBranch>’
--If the local branch does not exist, ‘pull’ command will create it. git pull origin B1:localBranch --branch list in verbose mode git branch -vv
localBranch 61435ed Adding the author
What did we learn:
definition from ‘git push --help':
“Update remote refs along with associated objects”
git fetch vs git push
‘git fetch’ updates just the remote refs, however ‘git push’ updates the objects (commits, tree, tags, blobs) as well.
--If local branch tracks remote branch with the same name git push --Push commits to ‘origin’ from ‘master’ git push origin master --Push commits to ‘origin’ from ‘localBranch’ to ‘remoteBranch’ git push origin localBranch:remoteBranch --Push current branch to the same name on remote git push origin HEAD --Push from local branch to remote ‘master’ git push origin HEAD master
Scenario 1: ‘master’ set to track ‘origin/master’, make a commit on ‘master’ and push to remote repo.
echo "version:1.0">>README git add . && git commit -m 'add version:1.0' git push OR git push origin master
Scenario 2: Local branch ‘B1’ set to track remote ‘origin/uat’, make commits on local branch push to remote
* B1 483d296 [origin/uat: ahead 4] Merge branch 'uat' of github.com:divyabhushan/learnRemotes into B1
git push origin B1:uat To github.com:divyabhushan/learnRemotes.git 37d931b..483d296 B1 -> uat
Scenario 3: Push from a local branch ‘B2’ to a new remote branch with the --upstream or -u flag
* B2 61435ed Adding the author
git push -u origin B2:B2 OR git push -u origin B2
remote: https://github.com/divyabhushan/learnRemotes/pull/new/B2 remote: To github.com:divyabhushan/learnRemotes.git * [new branch] B2 -> B2 Branch 'B2' set up to track remote branch 'B2' from 'origin'.
To push the tags to the remote repository, use the --tags flag
git push --tags origin master git push --tags origin localBranch:RemoteBranch
Checkout ‘origin/B1’ locally into a new branch ‘localB1’
git checkout -b localB1 origin/B1
Branch 'localB1' set up to track remote branch 'B1' from 'origin'. Switched to a new branch 'localB1'
Make a commit on ‘localB1’, tag the commit and push to remote branch ‘B1’
--Edit the README file. echo "push to remote repo">>README --Add file to Index and commit git add . && git commit -m 'push to remote repo' --Tag the latest commit. git tag -a v1.4 -m 'push to remote' --check the working dir status git status
On branch localB1 Your branch is ahead of 'origin/B1' by 1 commit. (use "git push" to publish your local commits) nothing to commit, working tree clean
git branch --delete <refname> OR git branch <remoteName> :branchName
List the remote branches
git branch -r origin/B1 origin/dev origin/localB1 origin/master origin/prod origin/remoteB2 origin/remoteBranch origin/uat
NOTE: Any local branches tracking the deleted remote branch will have a disconnected reference.
Let’s create a local branch ‘localBranch’ to track ‘remoteBranch’
git checkout -b localBranch origin/remoteBranch Branch 'localBranch' set up to track remote branch 'remoteBranch' from 'origin'. Switched to a new branch 'localBranch'
Delete the ‘remoteBranch’
git push origin --delete remoteBranch To github.com:divyabhushan/learnRemotes.git - [deleted] remoteBranch
--Update remote reference git fetch git branch -vv * localBranch d45cfd6 [origin/remoteBranch: gone] another edit from master
Every checkout to a lost upstream local branch will also list this information
git checkout master git checkout localBranch Switched to branch 'localBranch' Your branch is based on 'origin/remoteBranch', but the upstream is gone. (use "git branch --unset-upstream" to fixup)
Unset the upstream to the ‘remoteBranch’ from ‘localBranch’
git branch --unset-upstream
NOTE: Tags can also be deleted on the remote repository.
git push <remoteName> --delete <tag_name> git push origin --delete t_v1.1
To github.com:divyabhushan/learnRemotes.git - [deleted] t_v1.1
In case of large projects, the main repository used for ‘sharing’ is created as a ‘bare’ repository.
git init --bare <url> <directory> git init --bare --shared=770 <directory> ssh <user>@<host> cd path/above/repo git init --bare my-project.git
Task: Use Git repo as a Centralized repo shared among different users
Ssh key of linux server added on github.com
ssh established between Linux server and Mac host OS.
Step 1: On Linux server (or local repository) clone the GitHub hosted (Cloud) repository with bare option and initial setup
cd /tmp mkdir bareRepo git init --bare –shared git clone --bare --shared https://github.com/divyabhushan/bareRepo.git bareRepo chgrp -R home bareRepo git config core.sharedRepository 0770
NOTE: ‘git hooks’ covered in Module 8.
#Need a post_update hooks script to set the right permissions among the group users to be able to share the repository files. #Every time a user pushes to the bare repository, set the group as “home” and “770” permissions vi hooks/post_update #!/bin/sh sudo chmod -R 770 /tmp/bareRepo/* sudo chgrp -R home /tmp/bareRepo/* #All the users of the “home” directory should be given permissions to execute the above commands as sudo in the (/etc/sudoers file) %home ALL=(ALL) NOPASSWD: /bin/chmod -R 770 /tmp/bareRepo/* , /bin/chgrp -R home /tmp/bareRepo/* #Group and Users on CentOS Group: home
Users: divya, user1, user2
Step 2: Clone this repository on local Mac host OS and get working dir
cd ~ ; mkdir user1 user2 cd user1; git clone firstname.lastname@example.org:/tmp/bareRepo centOS_repo cd user2; git clone email@example.com:/tmp/bareRepo centOS_repo #Set the username and email for each user respectively git config user.name “user1/2” git config user.email firstname.lastname@example.org --check the remote url: git remote -v
origin email@example.com:/tmp/bareRepo (fetch)
origin firstname.lastname@example.org:/tmp/bareRepo (push)
Step 3: Make a commit as “User1”
echo "#version: 1.0" > README git add . && git commit -m "Adding README file." * 24aa91d 2018-09-27 | Adding version:1.0 of README file. (HEAD -> master) [user1]
Step 4: Push the “User1” changes to the Linux server bare repo
git push -u origin master
Step 5: Sync the “user2” with the Linux server
cd user2/centOS_repo git fetch origin git status
Step 6: Pull the latest commits into “User2” from the linux server bare repo
git pull origin master
Step 7: Make some commits as “user2” and push back to Linux server
echo “This is a readme file”>>README git add . && git commit -m ‘Updating README’ git push origin master
Step 8: Switch as “user1” and pull these changes
cd user1/centOS_repo git fetch origin git pull origin master
Thanks for the post. I liked the way all the details have been provided!
Firstly thanks for providing this tutorial from this article I have gathered lots of information. I can say that whatever the information provided by knowledgeHut is more useful to know more about the git.