10X Sale
kh logo
All Courses
  1. Tutorials
  2. DevOps

Collaboration Basics

Updated on Aug 29, 2025
 
13,121 Views

1. Clone Repositories – Git Collaboration

This git clone tutorial shows how to collaborate on GitHub

Command: git clone: Clones a repository into a new directory

  1. Clones the entire existing repo with complete project history
  2. creates a working copy
  3. creates a remote connection(reference) to the original repo.
  4. Creates and checks out an initial branch that is forked from the cloned repo’s currently active branch.

Image

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.

a) Git protocols

<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://divya@example.com/path/to/repo/myProject.git
#Clone from a remote server: git clone divya@centos.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.

2. Remotes

visualize and add/rename/delete remote refs

“remotes” refer to remote connections to other repos.

It’s a short name for a long URL or references to a commit, such as a branch, tag, HEAD, remote branch.

  1. Unlike Centralized VCS, git manages remote repositories just like any other full git repository.
  2. Different repos can be connected with each other and share the differences of data.
  3. Few repos with full access, few with read-only access etc.

Step 1: Clone the project

Under your home directory, run the below git clone command:

Image

git clone http://github.com/divyabhushan/learnRemotes.git learnRemotes

A new directory ‘learnRemotes’ will be created, this is your working directory

Image

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:

Image

$git remote
origin

Step 3: Verbose and show remote URL

Image

--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

Image

--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.

Image

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>

Image

git remote rename myProj LocalRepo_myProj

--list the remotes
git remote

Image

LocalRepo_myProj   --renamed
origin
origin2

Step 6: Remove a remote repository reference

This will only remove the remote reference to the repo.

Image

--remove the duplicate reference to ‘origin’ repo
git remote remove origin2

--List the remotes
git remote

Image

LocalRepo_myProj
origin

3. Remote Branches: List And Track Branches

(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:

Image

git branch --remote
OR
git branch -r

Image

 origin/B1
 origin/dev
 origin/localB1
 origin/master
 origin/prod
 origin/remoteB2
 origin/uat

Step 8: List the local branches tracking remote branches

Image

$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.Image

$ git checkout --track origin/dev
Branch 'dev' set up to track remote branch 'dev' from 'origin'.
Switched to a new branch 'dev'

Advanced command:

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.

Image

$--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’

Image

git checkout -b dev2

--list the branches in verbose mode:
git branch -vv

Image

 dev    e422743 [origin/dev] Merge branch 'localB1'
* dev2   e422743 Merge branch 'localB1'
 master d45cfd6 [origin/master] another edit from master

Image

--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'.

Image

--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.

Image

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.

Image

--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

4. Synchronize Local and Remote Repo

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’.

Image

--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

Image

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

Image

--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:

Image

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:

Image

git fetch --dry-run <remote_name>
example:
git fetch --dry-run origin

REMEMBER:

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>’

Pruning:

‘git fetch’ facilitates the removal of stale references to remote repository from your local repository.

  1. A branch deleted on remote repo – Its local reference will have to removed:
    Image
--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:

Image

--Review what is going to pruned
git fetch --prune --dry-run origin

From /Users/Divya1/OneDrive/gitRepos/test/remoteRepo
- [deleted]         (none) -> origin/uat

Image

--Fetch origin
git fetch --prune origin

From /Users/Divya1/OneDrive/gitRepos/test/remoteRepo
- [deleted]         (none) -> origin/uat

Image

--Remote reference to origin/uat now removed
git branch -r

git branch -vv
* uat    a109623 [origin/uat: gone] add version:1.0

NOTE:

Alternatively, ‘git remote prune’ command also prunes the references

Image

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.

b) git pull

‘git pull’ = ‘git fetch’ + ‘git merge’

Definition from manual page:

“Fetch from and integrate with another repository or a local Branch”

Image

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.
<options>:
--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’

  1. Checkout ‘master’; delete the latest commits and reset --hard to first commit and check history ‘git hist’.
  2. ‘git branch -vv’ command shows ‘master’ behind ‘origin/master’ by 5 commits.
  3. Check the difference in code between ‘master’ and ‘origin/master’: ‘git diff’ command.
  4. Pull changes into ‘master’ from ‘origin/master’: ‘git pull’ command.
  5. Check the ‘master’ history: ‘git status’ and working directory status: ‘git status’

    Image
cd learnRemotes
git checkout master
git reset --hard 0847197

--Show verbose list of local and remote branches
git branch -vv

Image

--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

Image

$git hist
* 0847197 2015-04-05 | Initial import, README added (HEAD -> master) [divya]

Let us see the 5 commit logs missing in ‘master’

Image

$ 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’

Image

$ 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’

Image

git pull origin master

Image

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.

Image

git hist

Image

* 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.

Image

git status

Image

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

Image

git checkout -b B1 0847197

Image

Switched to a new branch 'B1'

Check history of branch ‘B1’

Image

git hist

Image

* 0847197 2015-04-05 | Initial import, README added (HEAD -> B1) [divya]

Set “B1” to track “origin/B1” and pull changes from remote

Image

git branch --set-upstream-to=origin/B1
Branch 'B1' set up to track remote branch 'B1' from 'origin'.

Show verbose listing of branches

Image

$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’

Image

--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:

Image

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’:

Image

git hist

Image

* 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]

Scenario:
‘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

Image

git checkout B1
git branch --unset-upstream
git branch -vv

Image

--B1’ not tracking ‘origin/B1’ anymore
* B1     61435ed Adding the author

‘git pull’ command will fail

Image

git pull

Image

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>’

Image

--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

Image

localBranch 61435ed Adding the author

NOTE:

  1. You will need to setup ‘localBranch’ to track the remote ‘origin/B1’ branch; this will not be setup automatically.
  2. ‘localBranch’ has the latest commit as ‘origin/B1’

What did we learn:

  1. ‘git pull’ command is used to update your local repository with the remote repo.
  2. Individual local branches can be set up to track the remote branches; any commit update in the remote branch will be tracked and can be pulled into local branch.
  3. ‘git pull’ will create a new branch if the local branch does not exist.

c. git push: Push the local commits to the remote repository

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.

Image

--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
echo "version:1.0">>README
git add . && git commit -m 'add version:1.0'

git push
OR
git push origin master

Result:

  • Local ‘master’ commits pushed onto remote ‘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

Image

git push origin B1:uat

To github.com:divyabhushan/learnRemotes.git
  37d931b..483d296  B1 -> uat

Result:

  • Local ‘B1’ commits pushed onto remote ‘origin/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

Image

git push -u origin B2:B2
OR
git push -u origin B2

Result:

  • Local ‘B2’ commits pushed onto remote ‘origin/B2’ with the same name
  • ‘origin/B2’ will be created if does not exists
  • ‘B2’ will be set to track ‘origin/B2’
    Image
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

Image

git push --tags origin master
git push --tags origin localBranch:RemoteBranch

Checkout ‘origin/B1’ locally into a new branch ‘localB1’

Image

git checkout -b localB1 origin/B1

Image

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’

Image

--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

Image

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

d. Delete remote branches

origin/remote branch

  1. Remote branches can be deleted from the local working directory, keeping in mind not to delete the main development branch or a shared release branch.
  2. Private topic branch which has been merged into the main branch is safe to delete.

    Image
git branch --delete <refname>
OR
git branch <remoteName> :branchName

List the remote branches

Image

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’

Image

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’

Image

git push origin --delete remoteBranch

To github.com:divyabhushan/learnRemotes.git
- [deleted]         remoteBranch

Image

--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

Image

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’

Image

git branch --unset-upstream

NOTE: Tags can also be deleted on the remote repository.

Image

git push <remoteName> --delete <tag_name>

git push origin --delete t_v1.1

Image

To github.com:divyabhushan/learnRemotes.git
- [deleted]         t_v1.1

5. Bare and Development Repositories

In case of large projects, the main repository used for ‘sharing’ is created as a ‘bare’ repository.

Command used:

git init --bare <url> <directory>
git init --bare --shared=770 <directory>
ssh <user>@<host>
cd path/above/repo
git init --bare my-project.git

Image

Task: Use Git repo as a Centralized repo shared among different users

  • Bare repository has no working copies, you cannot modify files or commit.
  • You also cannot push to a bare repository but to its cloned repo.
  • Shared/Central storage repositories should be bare repositories.
  • There is no .git directory created. Instead, the files normally in the .git directory are placed in the top-level root directory where the working directory would normally be.

Pre-requisite:

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 user1@centos.com:/tmp/bareRepo centOS_repo
cd user2; git clone user2@centos.com:/tmp/bareRepo centOS_repo

#Set the username and email for each user respectively
git config user.name “user1/2
git config user.email user1/2@email.com

--check the remote url:
git remote -v

origin user1@centos.com:/tmp/bareRepo (fetch)

origin user1@centos.com:/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
+91

By Signing up, you agree to ourTerms & Conditionsand ourPrivacy and Policy

Get your free handbook for CSM!!
Recommended Courses