Git: How it goes and important commands for beginners
Git is a versioning control system(VCS) that makes it easier to track changes to files. For example, when you edit a text file, git can help you determine exactly what changed, who changed it, and why. Mainly it is useful in coordinating with multiple developer working on same projects at same time. Git provides flexibility to developer to work on a project independently without effecting other’s work. Here is a scenario, A team of 50 developers working on a project at same time and updating code continuously. Same time other developer updating the same code with her/his changes which causes the conflict. How this conflict can be avoided.
Developer can cut a separate local branch and start doing her/his changes. Once changes are done, developer has to take the pull from the master branch, resolve the conflicts, if any and push changes into master branch of repository. Once the changes are merged to the main master branch then it will be visible to other developers as well. Below are the series of commonly used commands.
- Create an empty git repository or reinitializes if already exists.. It will create a .git directory in your current directory which will have few important directories and files.
ansible[@[:~/ansible$ git init
ansible[@[:~/ansible$ cd .git
ansible[@[:~/ansible$ ls -lart
drwxr-xr-x+ objects
drwxr-xr-x+ info
drwxr-xr-x+ hooks
-rw-r — r — + description
-rw-r — r — + config
-rw-r — r — + HEAD
HEAD: Content of HEAD file refers to different file ref: refs/heads/master . The file contains the hash of the most recent commit on the master branch
- Clone a repository
ansible[@[:~/ansible$ git clone https://github.com/ansible/ansible.gitCloning into ‘ansible’…remote: Counting objects: 306502, done.
remote: Compressing objects: 100% (16/16), done.
remote: Total 306502 (delta 10), reused 0 (delta 0), pack-reused 306486
Receiving objects: 100% (306502/306502), 109.82 MiB | 2.55 MiB/s, done.
Resolving deltas: 100% (194314/194314), done.
Checking connectivity… done.
ansible[@[:~/ansible$
- List the current branch
ansible[@[:~/ansible/ansible$ git branch
* devel
ansible[@[:~/ansible/ansible$
- List all the branches
ansible[@[:~/ansible/ansible$ git branch -a
* devel
remotes/origin/HEAD -> origin/devel
remotes/origin/devel
remotes/origin/release1.5.0
remotes/origin/release1.5.1
remotes/origin/release1.5.2
remotes/origin/release1.5.3
remotes/origin/release1.5.4
remotes/origin/release1.5.5
remotes/origin/release1.6.0
remotes/origin/stable-1.9
remotes/origin/stable-2.0
remotes/origin/stable-2.0-network
remotes/origin/stable-2.0.0.1
remotes/origin/stable-2.1
remotes/origin/stable-2.2
remotes/origin/stable-2.3
remotes/origin/temp-staging-post-2.4.4
remotes/origin/threading_instead_of_forking
remotes/origin/threading_plus_forkingansible[@[:~/ansible/ansible$
- Checkout a branch. Refer: Git Checkout
ansible[@[:~/ansible/ansible$ git checkout release1.5.0
Branch release1.5.0 set up to track remote branch release1.5.0 from origin.
Switched to a new branch 'release1.5.0'ansible[@[:~/ansible/ansible$ git branch
devel
* release1.5.0
ansible[@[:~/ansible/ansible$
- Take pull for the latest changes (If there are changes in local copy then resolve the conflict first). To resolve the conflicts Refer: How to resolve conflicts in git
ansible[@[:~/ansible/ansible$ git pull
remote: Counting objects: 7, done.
remote: Total 7 (delta 4), reused 4 (delta 4), pack-reused 2
Unpacking objects: 100% (7/7), done.
From https://github.com/ansible/ansible
0a6b951..190755f devel -> origin/devel
Already up-to-date.
ansible[@[:~/ansible/ansible$
- Create a branch local_changes to start your changes.
We have created a local branch named local_changes but pointer is still referring to release1.5.0. We need to checkout the branch before start working.
ansible[@[:~/ansible/ansible$ git branch
devel
local_changes
* release1.5.0
ansible[@[:~/ansible/ansible$
- Delete a local branch local_changes ( using -d flag ).
ansible[@[:~/ansible/ansible$ git branch -d local_changes
Deleted branch local_changes (was 6221a27).
ansible[@[:~/ansible/ansible$ git branch
devel
* release1.5.0
ansible[@[:~/ansible/ansible$
- Create and checkout a branch local_changes directly.
ansible[@[:~/ansible/ansible$ git checkout -b local_changes
Switched to a new branch 'local_changes'
ansible[@[:~/ansible/ansible$ git branch
devel
* local_changes
release1.5.0
ansible[@[:~/ansible/ansible$
- Make the changes into code and check status. It will give you the list of files added/deleted/updated.
We have created a new file named ansible.yml and updated file setup.py . Currently both files are untracked.
ansible[@[:~/ansible/ansible$ git status
On branch local_changes
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)modified: setup.pyUntracked files:
(use "git add <file>..." to include in what will be committed)ansible.ymlno changes added to commit (use "git add" and/or "git commit -a")
ansible[@[:~/ansible/ansible$
- Take the diff and verify the changes with master branch. Plus + sign shows newly added lines in setup.py file.
ansible[@[:~/ansible/ansible$ git diff setup.py
diff --git a/setup.py b/setup.py
index c537ee9..bfb0462 100644
--- a/setup.py
+++ b/setup.py
@@ -22,6 +22,24 @@ data_files = []
for i in dirs:
data_files.append((os.path.join(install_path, i), glob('./library/' + i + '/*')))
+
+print "Adding a test statement"
- Move the changed files into staging.
New file ansible.yml is moved staging area and ready to commit now.
ansible[@[:~/ansible/ansible$ git add ansible.yml
ansible[@[:~/ansible/ansible$ git status
On branch local_changes
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)new file: ansible.ymlChanges not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)modified: setup.pyansible[@[:~/ansible/ansible$
- If wanted to move the changes back to unstaging. Using below command, we are on the same place where we were before git add.
ansible[@[:~/ansible/ansible$ git reset HEAD ansible.yml
Unstaged changes after reset:
M setup.py
ansible[@[:~/ansible/ansible$ git status
On branch local_changes
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)modified: setup.pyUntracked files:
(use "git add <file>..." to include in what will be committed)ansible.ymlno changes added to commit (use "git add" and/or "git commit -a")
ansible[@[:~/ansible/ansible$
- If wanted to work on other branch and commit it into master due to some immediate issue then git stash can be used. Stash is very nice feature provided by git. Refer page to understand git Stash.
ansible[@[:~/ansible/ansible$ git stash
Saved working directory and index state WIP on local_changes: 6221a27 Updating files for new upstream release 1.5.0
HEAD is now at 6221a27 Updating files for new upstream release 1.5.0ansible[@[:~/ansible/ansible$ git status
On branch local_changes
Untracked files:
(use "git add <file>..." to include in what will be committed)ansible.ymlnothing added to commit but untracked files present (use "git add" to track)ansible[@[:~/ansible/ansible$ git stash list
stash@{0}: WIP on local_changes: 6221a27 Updating files for new upstream release 1.5.0
- Commit the Changes.
ansible[@[:~/ansible/ansible$ git add setup.py
ansible[@[:~/ansible/ansible$ git commit -m 'Added print statement in file setup.py'
[local_changes 74139d3] Added print statement in file setup.py
1 file changed, 2 insertions(+)ansible[@[:~/ansible/ansible$ git status
On branch local_changes
Untracked files:
(use "git add <file>..." to include in what will be committed)ansible.ymlnothing added to commit but untracked files present (use "git add" to track)
ansible[@[:~/ansible/ansible$Note: We can see ansible.yml is still untracked as we have not added this file for commit.
- Till this point changes are committed into the local branch local_changes only. Changes are available on local system only which can be verified by checking git logs.
It will provide the list of commits with their hash, author name and date
ansible[@[:~/ansible/ansible$ git log
commit 74139d323f4c9cbbd5b1f78f0e33017dcd67042f
Author: OpenInfo <OpenInfo.collection@gmail.com>
Date: Sat Mar 17 17:27:26 2018 -0700Added print statement in file setup.pycommit 6221a2740f5c3023c817d13e4a564f301ed3bc73
Author: James Cammarata <jcammarata@ansibleworks.com>
Date: Fri Feb 28 14:17:07 2014 -0600Updating files for new upstream release 1.5.0
- Push the changes into remote.
Directly trying to push the branch on remote will fail due to local_changes branch unavailability at remote site. So we need to explicitly tell the information of upstream.
ansible[@[:~/ansible/ansible$ git push
fatal: The current branch local_changes has no upstream branch.
To push the current branch and set the remote as upstream, usegit push --set-upstream origin local_changesansible[@[:~/ansible/ansible$ git push --set-upstream origin local_changes
Username for 'https://github.com': OpenInfo
Password for 'https://OpenInfo@github.com':
- If you are the admin of repository then you good to go or else Go to the github UI and Create a pull request and ask administrator to merge into master branch.