top

Search

GIT Tutorial

1. Clone repositories – git collaborationThis git clone tutorial shows how to collaborate on githubCommand: git clone: Clones a repository into a new directoryClones the entire existing repo with complete project historycreates a working copycreates a remote connection(reference) to the original repo.Creates and checks out an initial branch that is forked from the cloned repo’s currently active branch.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/pathThere 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. Remotesvisualize 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.Unlike Centralized VCS, git manages remote repositories just like any other full git repository.Different repos can be connected with eachother and share the differences of data.Few repos with full access, few with read-only access etc..Step 1: Clone the projectUnder your home directory, run the below git clone command:git clone http://github.com/divyabhushan/learnRemotes.git learnRemotesA new directory ‘learnRemotes’ will be created, this is your working directoryCloning 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 reposList the remote repository for this local working directory:$git remote originStep 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 -vNOTE: 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 namegit remote rename <old-name> <new-name>git remote rename myProj LocalRepo_myProj --list the remotes git remoteLocalRepo_myProj --renamed origin origin2Step 6: Remove a remote repository referenceThis will only remove the remote reference to the repo.--remove the duplicate reference to ‘origin’ repo git remote remove origin2 --List the remotes git remoteLocalRepo_myProj origin3. 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:git branch --remote OR git branch -r origin/B1  origin/dev  origin/localB1  origin/master  origin/prod  origin/remoteB2  origin/uatStep 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 authorNOTE: 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'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.$--verbose mode of branch listing git branch -vv * uat       37d931b [origin/uat] local branch1 notes addedStep 9: Manually set the local branch to track the remote(upstream) branchCreate 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 masterNOTE: 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 master4. Synchronize local and remote repoa) ‘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 --tagsgit 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/uatWe 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 originREMEMBER: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.A branch deleted on remote repo – Its local reference will have to removed:--List remote branch git branch -r origin/uat git branch -vv * uat    a109623 [origin/uat] add version:1.0git 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.0NOTE: Alternatively, ‘git remote prune’ command also prunes the referencesgit remote prune origin --dry-run Pruning origin URL: /Users/Divya1/OneDrive/gitRepos/test/remoteRepo/ * [would prune] origin/uatRun 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”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 branchesCase 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’Checkout ‘master’; delete the latest commits and reset --hard to first commit and check history ‘git hist’.‘git branch -vv’ command shows ‘master’ behind ‘origin/master’ by 5 commits.Check the difference in code between ‘master’ and ‘origin/master’: ‘git diff’ command.Pull changes into ‘master’ from ‘origin/master’: ‘git pull’ command.Check the ‘master’ history: ‘git status’ and working directory status: ‘git status’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 addedaIt’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 masterFrom 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.git hist* 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.git statusOn branch master Your branch is up to date with 'origin/master'. nothing to commit, working tree cleanCase 2: Pull from a remote branch into a local branchCreate a “B1” branch from the initial “master” historygit checkout -b B1 0847197Switched to a new branch 'B1'Check history of branch ‘B1’git hist* 0847197 2015-04-05 | Initial import, README added (HEAD -> B1) [divya]Set “B1” to track “origin/B1” and pull changes from remotegit 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 addedNOTE: 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:B1Either 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’:git hist* 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’ commandgit 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 git pullThere 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> B1Solution 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 -vvlocalBranch 61435ed Adding the authorNOTE:You will need to setup ‘localBranch’ to track the remote ‘origin/B1’ branch; this will not be setup automatically.‘localBranch’ has the latest commit as ‘origin/B1’What did we learn:‘git pull’ command is used to update your local repository with the remote repo.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.‘git pull’ will create a new branch if the local branch does not exist.c. git push: Push the local commits to the remote repositorydefinition 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 masterScenario 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 masterResult: 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 B1git push origin B1:uat To github.com:divyabhushan/learnRemotes.git   37d931b..483d296  B1 -> uatResult: 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 authorgit push -u origin B2:B2 OR git push -u origin B2Result: 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’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 flaggit push --tags origin master git push --tags origin localBranch:RemoteBranchCheckout ‘origin/B1’ locally into a new branch ‘localB1’git checkout -b localB1 origin/B1Branch '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 statusOn 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 cleand. Delete remote branchesorigin/remoteBranchRemote branches can be deleted from local working directory, keeping in mind not to delete the main development branch or a shared release branch.Private topic branch which has been merged into the main branch is safe to delete.git branch --delete <refname> OR git branch <remoteName> :branchNameList the remote branchesgit branch -r origin/B1 origin/dev origin/localB1 origin/master origin/prod origin/remoteB2 origin/remoteBranch origin/uatNOTE: 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 masterEvery checkout to a lost upstream local branch will also list this informationgit 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-upstreamNOTE: Tags can also be deleted on the remote repository.git push <remoteName> --delete <tag_name> git push origin --delete t_v1.1To github.com:divyabhushan/learnRemotes.git - [deleted]         t_v1.15. Bare and development repositoriesIn 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.gitTask: Use Git repo as a Centralized repo shared among different usersBare 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.comssh 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 setupcd /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 0770NOTE: ‘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: homeUsers: divya, user1, user2  Step 2: Clone this repository on local Mac host OS and get working dircd ~ ; 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 -vorigin 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 repogit push -u origin masterStep 5: Sync the “user2” with the Linux servercd user2/centOS_repo git fetch origin git statusStep 6: Pull the latest commits into “User2” from the linux server bare repogit pull origin masterStep 7: Make some commits as “user2” and push back to Linux serverecho “This is a readme file”>>README git add . && git commit -m ‘Updating README’ git push origin masterStep 8: Switch as “user1” and pull these changescd user1/centOS_repo git fetch origin git pull origin master
logo

GIT Tutorial

Collaboration basics

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

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

Repo-TO-Repo Collaboration

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 shortname for a long url or references to a commit, such as a branch, tag, HEAD, remote branch.

  • Unlike Centralized VCS, git manages remote repositories just like any other full git repository.
  • Different repos can be connected with eachother and share the differences of data.
  • 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:

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

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:

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'

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.

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

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

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

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:

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

NOTE: 

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.

b) git pull

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

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.

git hist

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

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

git hist

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

git hist

* 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

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 

git pull

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

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.

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

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

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

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’

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

d. Delete remote branches

origin/remoteBranch

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

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

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

Bare and development repositories

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 8Switch as “user1” and pull these changes

cd user1/centOS_repo
git fetch origin
git pull origin master

Leave a Reply

Your email address will not be published. Required fields are marked *

Comments

stephen

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.

Saurabh

Written nicely