Thursday, September 21, 2017

Git Study -2



File Status life cycle in Git





UnTracked: When a new file is created or added to the repository, Git will not track it untill we include it in our repo by using the –add Command.

    Once ‘added’, the state of the file becomes ‘UnModified’ and it is ready to be modified or commited. 
    If modified, the file state becomes ‘Modified’ and it is ready to be commited i.e it has reached the staging area also called as Index.

Staging area or Index is a virtual place that collects all the files that we want to include in the next commit.
-When we modify a content and not committed it, then it is still in the working directory and will show as modified in each and every branch of repository, until we commit it to some specific branch.


-Files in the working directory can be   a) Tracked or b)  UnTracked
After adding, the files becomes tracked. 
The Tracked Files can be a) Modified or  b) UnModified or c) Staged
 





To make proper good of Git, just avoid
1. working hard on the same file on different branches.
2. Rarely merging the branches.

-          A Hash is a name, whereas a ref is a pointer to a commit.
The default shell that comes with GitHub for windows is PoshGit, which is windows power shell environment for git.
Poshgit will let you use windows and powershell commands with Git at the command line. On the other hand, GitBash uses Bash Shell (Bourne Again Shell) which is part of a Linux style environment and command line tools.

-          Common Rules for Rebasing in Git:
1.   Never Rebase after pushing a branch.
2.   Never rebase after commits use your branch.
            3. Never rebase after pulling someone else’s branch.



Git Personalization configuration and settings can be applied at
     1. System configs : These are available for all the users and repositories on the system .ie. TOP LEVEL
     2.  Global configs: These are available for all the repos of current user.(MIDDEL LEVEL)
    3.  Repository Level configs : These are only available for current Repo.(LOWEST LEVEL)

Every config parameter can be set a every level and if the same parameter is set at different levels, then the lowest level parameter hides the top level parameter.


For System level config we use the --System flag.
For user specific settings we use the  -- global flag.
For Repository level config we use the --local flag.
 If we don’t specify any of these options, then the config setting will take place only in the current repository we are in now.


Global settings are stored in ~/.gitconfig and local settings are stored in the file .git/config for the repo we are working on.
 

> to edit the .gitconfig in a text editor
> vi  ~/.gitignore    {here “vi” is a text editor, press “I” to  go into editor mode and “wq” to save n exit.}



Available protocols for any git remote
1.   Local Protocols – Cloning to the local system. Limited access.
2.   Git Protocol-  Only read-only so cant push. No security provided.
3.   Http/https Protocols: connection is encrypted. If repo is public, we can  clone/pull anonymously over https. For pushing, credentials verified. Https always works even if we are behind any firewall/proxy.
4.   SSH Protocol: Git recommends using https over ssh.

 

-For pushing over https, credentials are verified repeatedly , so to remember credentials use below, default is 15 mins.

Git config --global credential.helper cache
We can also set Timeout in seconds eg. For one hour
git config –global credential.helper ‘cache –timeout=3600’



GIT PUSH
git push origin master
origin: it is our remote destination that we set by using remote add command.
Master: it is our current active branch.

git push simply pushes the code in the current branch to the remote origin branch of the same name. Branch is created on the origin if not already present.
git   push -u -- set-upstream origin – all

git push remote_branch_name : pushes the code in the current branch to the named branch on the remote.

git push ‘origin_remote_branchname’     ‘localbranchname’
Above command pushes our code from the local ‘localbranchname’ (irrespective of our current branch) to the remote branch of the same name on the remote. If the remote branch not exists, then it will get created.

git push remote_name         local_branch : remote_branch
Above command pushes the local_branch from the local repository to the remote_branch of the remote.
Above command can also be used to delete a branch on the remote. eg.
git push   remote_name               : remote_branch
Note that we are sending an empty branch to the ‘remote_branch’ branch of remote, which empties the remote_branch i.e deletes it on the remote.

git push  -u    origin     mybranch
Here we are uploading our ‘mybranch’ branch(with all the commits in it) to the remote origin.
The –u option is used to track a remote upstream branch i.e it will tie our local branch with remote one. This process is not automatic. We have to set it manually using –u flag. So that when we use git –fetch command, then we get changes from all the tracked branches.

Use      git config --  global   push.default    nothing        = to change the default push settings. Now we have to mention the target branch everytime.
Use     git config – global push.default      simple   =  Now git will push only when there is remote branch with the same name as that of the local branch.





GIT PULL
To update local repos, we first download and then merge.
git fetch remote_name (or )     git fetch

Following a fetch, we have to merge eg.
To update the local master branch with the remote master branch, we use
git merge   origin / master                 it will update the currently active branch.

Git Pull is essentially a Git Fetch followed by a get merge.
-          To update currently active branch.
git pull origin master
Like merge, git pulls are fast-forward by default. but can be overridden by – no- ff postfix.

Like push, we can specify different local and remote branches for pull too.
git pull    or git pull remote_name         by default, it pulls the code from the master branch of the origin remote and merges into currently active branch, or we can also give name of the remote branch.
git pull remote_name      branch_name
It pulls code from the ‘branch_name’ branch of the ‘remote_name’ remote and then merges to the currently active branch.

git pull remote_name     local_branch : remote_branch
it pulls code from the ‘remote_branch’ branch of the ‘remote_name’ remote and merges with the ‘local_branch’ branch in the local repository.





GIT Commands

git add –a  : Add changes from all tracked and untracked files.

git add –u :  Do not add new files. Only add changes to the currently tracked files and removals to the next commit.

git add .  :   Do not add removals. Add new or changed files to Staging.

git commit –a  : We can skip (adding to staging) of a modified file by postfixing –a to git commit which performs add operation. But “-a” only adds tracked files hence we might lose any untracked files that we wanted in the commit. Also  “git commit –a “ would add all the changed files in the same commit.

git branch  ‘brach_name’   Base
creates a branch based on existing one. eg.       git  branch   testbranch    HEAD

git add  -P          Shows the path and staging hunks. Partial commit.

-          To unstage a file after git add, we use
‘git  reset HEAD  myfile’       or ‘git reset myfile’ but changes will be retained in the working directory. and to undo the changes in the working directory, use   ‘git checkout myfile’

git reset – soft HEAD~1
To undo a commit. The soft option undoes a commit but lets the changes we made in that commit remain staged for us to review.


-To create a branch based on certain commit
git  checkout  -b   mynewBranch    cafdef


-To rename current branch
git  branch   -m     renamedBranchName
The  ‘-m’  flag : move/rename a branch and its reflog.
The  ‘-M’  flag : move/rename a branch even if the target already exists. ie. overwrites it.


To delete a branch
git branch   -D  branchname
git branch   -d branchName
‘-d’ flag will delete the branch only if it has been synched i.e it will only delete a fully merged branch.
‘-D’ flag will delete the branch even if it is not merged.


A branch is just a link between different commits and HEAD of a branch points to the latest commit in the branch. i.e. HEAD and the tip of the current branch points to the same commit.

-          -- ff merge  :   Only the branch path way is changed and the HEAD of the branch is updated. It is default.
-          -- no - ff     :  A new commit is created on the base branch with the changes from the other (to-be-merged) branch.  eg….
git merge  -- no -ff  newFeatureBranch
If there is diverging history, then there can’t be  a  --no -ff merge.


 
-          alias   gl = ’git log -- oneline -- all -- graph --decorate’

To unstage a file
git rm  --  cached [file]


git diff :      Without any flag it compares whats in the staging area with whats in the working area. i.e difference of what is changed but not staged.

git diff -- staged
To compare Staged and Committed git repository. ie.
difference of what is staged but not yet committed.

git diff (file_name)  Show changes in single file compared to last commit

To compare working directory with the git repository ie. without taking into account staging area
diff  HEAD <filename>
HEAD is actually a reference to the last commit on the current branch.


git diff   branchB -- branchA
Shows the difference of what is in branchA that is not in branchB.
git diff  <sourceBranch>  <targetBranch>
CTM : Note that the differences are shown from the point of view of the targetBranch.


git log   : Shows the commit history for the currently active branch.

git log  branchB -- branchA    Shows the commits  on branchA that are not on branchB.

git log --follow [filename]
Shows the commits that changed the file, even across renames.

git log --stat -m
Show all commit logs with indication of any paths that moved.


git log --oneline --graph  -- all --decorate

git log --pretty = “%h, %cn, %cr”

git log -all
Shows commits in all branches including current branch.

To temporarily store modified, tracked files in order to change branch.
git  stash               : save modified and staged changes.
git stash list          : list stack order of stashed file changes.
git stash pop        :  write working from top of stash stack.
git stash drop   : discard the changes from top of stash stack.
git stash apply    : to apply changes that are stored in the last stash.

To restore an old stash, we mention the serial no. next to the stash in the list of stashes.
git stash apply stash@{1}
We can apply multiple stashes too.

Stash commands stashes the changes made to the Tracked files only. To add untracked files to the stash, we have to add them.


To see few latest commits
git log -n 2       or git log -2

git log --after=’2015-3-1’     or git log --since=’2015-3-1’
git log --before=’2015-3-1’   or git log --untill=’2015-3-1’

git shortlog     : shows the authors of commits and messages.

git log --author = ‘vikas’


To stage only a part of our changes to the same file use
git add -p
Git will club all the changes together into a hunk and give us options. A larger hunk can be further splitted into smaller hunks by using the option   ‘s’
CTM: After staging a part of the modified file, never commit the changes by using the ‘--a ’ option, as this would add the rest of the modified file too.

Cherry Pick  :  If we wanted to merge a single commit from one branch into another branch, then merge or rebase wont suffice. In merge and rebase we join our current branch with a different branch. ie. all the changes/commits that have happened since it diverged from our branch, will appear in our final branch after merge.
With cherry pick we can pick a single commit from a different branch and make it appear in our own branch eg.
git cherry -pick    abcdef    [this is the commitid of the commit]
git cherry -pick   -- continue      : continues the operation in progress.
git cherry -pick   -- abort    :   cancel the operation and return to the  pre-sequence state. 

git cherry -pick   --quit    : Forget the current operation in progress.
We can even pick the commit sets by using the   <startcommit>  -- <endcommit> syntax. eg.
git cherry-pick    mybranch~2 .. mybranch~0
By this syntax, we are picking the last two commits from the ‘mybranch’ branch.

Git enables searching in commit messages by using the  --grep option.
git log --grep = ‘redirect’       :  searches for ‘redirect’ in the messages.

Tags : The Tags are the labels for milestone commits in the repository. They can be used to mark changes being made without creating an extra branch. Tags provide an easy way to go back in history of branch.
git tag  : list the tags in alphabetical order.
git tag tagname  :  create a tag by the name of ‘tagname’
git show mytagname   : Show tag details

There exists two types of Tags.  Lightweight and Annotated.
LightWeight : only tagname and points to a commit.
Annotated : contains tagName, info about tagger and a message.
To create annotated tag
git tag -a myTagName -m ‘my commit message’

We can also checkout a Tag named ‘myTag’ by creating a new branch.
git checkout -b  myBranchName   myTag
By default, when we push our code to remote, our tags won’t get pushed.
To push our tags to the remote origin, we use
git push origin --tags
To specifically push a named Tag
git push  origin mytag



A Hash is a name whereas a ‘ref’ is a pointer to a commit. Refs are stored internally in Git.
HEAD is also a ref.
Some special refs are ORIG_HEAD, MERGE_HEAD, FETCH_HEAD
reflog is a ref of logs.
Any change we make in the Git is recorded and accessible via the reflog command ie. changes like commit, merge, checkout etc.
git  reflog
reflog command stores the records for each action we performed in our repository locally.
reflog can be used to review changes to our local repo and can also be used to recover lost commits. i.e. If during hard reset we lose some of our commits, then by using the reflog command we can find our lost commit hashes and by using these commit hashes we can checkout a new branch based on that hash.

The reflog command only track back changes for a certain time. Git automatically clears reflog data periodically ie. by default it is of 90 days. but we can also modify this time by using the ‘expire’ option of the command.
If you want reflog never to forget any action, then use
git reflog expire --expire = never

A commit is lost when it is not part of any branch. The log command fails to search and show lost commits.
Reasons for lost commits : 1. Hard Reset   2. Deleting branches without merge.
Lost commits are those that are recorded by Git, but are not present anywhere in our branches.
To search lost commits that are not part of any branch, use fsck (file system check) command.
git fsck --lost -found
To recover a lost commit c9067  from the above list to your current branch, use
git merge c9067 {this is the commitid hash of the commit.}

fsck VS reflog : There is an advantage of fsck over reflog.   for eg.
If we have cloned a remote branch and deleted it. Then the commits present there would never show up on the reflog, bcoz they were never done on our local system.  However, the fsck will list all the lost commits from that branch.

Rebasing is a way of rewriting the history of a branch by moving it to a new ‘base’ commit. It avoid loops in the project history.
If you are rebasing a master into branch B1, the new commits in master are put before the new commits in the branch B1 that are not common to master. To do this, use this command from the branch B1 i.e
git rebase master.

But if you are working in a team, then you should first checkout to master, then pull from the upstream branch to update your master with the latest commits and then switch back to branch B1 before running the ‘git rebase master’ command.
This above process can also be accomplished by using
git merge -- rebase master
Similarly we can also rebase with a pull by using
git pull --rebase origin master

 
There are three main differences in rebase as compared to merge:
1.   git rebase does not create any additional ‘commit’ objects.
 
2.   When running git rebase [other-branch] from the current-branch, then the git will first checkout the [other-branch] before re-applying the commits of the [current-branch].
Practically, this means that the [other-branch] will stand for ORIG_HEAD and [current-branch] will stand for MERGE-HEAD.

3.   git will drop a commit for which the computed diff is now empty.


Below will set the user credentials for the commit transactions at the user level. ie. all the repositories of the current user will use these credentials.
git config --global user.name
git config --global user.email

to make mergetool not to keep backup files after merging
git config --global mergetool.keepBackup false

Set Kdiff3 as merge tool
git config --global merge.tool kdiff3

Set diffmerge as diff tool for GIT.
git config --global diff.tool  diffmerge

Configure diffmerge command
git config --global diff.tool  diffmerge.cmd/usr/bin/diffmerge  LOCAL REMOTE


Shows the remote url
git config --get remote.origin.url

Enables colorization of command line output
git config --global color.ui.auto


save all uncommitted changes with messages.
git stash save message
git stash pop | list|drop|apply etc


git init [project-name]
creates a new local repo with the specified name


git status -s       Shows the git short status

git ls-files --other --ignored --exclude-standard
Shows the list of all ignored files

git gui blame [file-name]
Shows the file’s last content change history line by line

git bisect               Find by binary search, the change that introduced  a bug.

git remote rm origin
Removes origin  ssh link. This name will be deleted from the local git repo.


git remote show origin
Shows the url saved as origin.


git remote add <Name>   <url of remote repo>
Name = this is the name for remote repository link.

git remote set-url   origin    url
Sets remote url name as origin.

git rebase -i
“i” means ‘interactive’. For reordering, squashing and other purpose.

git rebase -i     HEAD~n
Reorder commits


git checkout
Total number of local commits ahead of remote origin.

git rebase -onto
Allows us to change the base of a commit or rebase it in a non-interactive way.

git checkout --
removes all uncommitted changes.

git clean  -df
deletes all untracked files.

git difftool
open difftool to view difference.

git pull  --rebase
To fetch and merge to latest CL (commit log)
Pull is equal to Fetch + merge.

git revert SHA2     SHA1
Use this when you have shared your codes. But you must revert your CL in reverse order.

git merge --squash  ‘branchname’
This command squashes all the commits of ‘branchname’ branch into one commit and merges into current branch.


git notes add [commit]
Add a note to a specific commit


git reset --hard
reset = Revert, Rollback. Permanently go back to previous commit.
It deletes all local commits. Use this only if we have not shared our code.

git reset --hard [SHA of commit]


git reset --soft  HEAD^
moves the mistakenly committed files back to the staging area from the previous commit.

git reset [filename]
unstages the file but preserves its changes locally.


git commit  --dry  -run
to see what changes will be committed before actually running the git commit.

$ git commit -a -m 'added new benchmarks'
git commit -am “(message)”
Add all changes to staging and commit them with message
you don’t have to run git add on the changed file in this case before you commit. That’s because the -a flag includes all changed files.
If you want to skip the staging area, Git provides a simple shortcut. Adding the -a option to the git commit command makes Git automatically stage every file that is already tracked before doing the commit, letting you skip the git add part:


git  rm  --cached  [filename]
removes the file from version control but preserves it locally.

git rm  [filename]
Deletes the file from working directory and stages the deletion.

git mv  [original_filename]      [new_filename]
Changes the filename and prepares it for the commit.

git rev -list HEAD   -- count
Total number of commits.

Fixing a previous bad commit
git checkout <badcommit>
git commit  --amend  -v
git rebase  --onto  HEAD [bad commit]  [checked-out-branch]



git rebase [branchname]
Apply any commits of current branch ahead of the specified branch.


To check which editor git will use
git config  --get  core.editor



To create alias
git config --global alias.co    checkout

git config --global  alias.cm   “commit -m”

git config --global alias.unstage   ‘reset HEAD --’   and then use like this > git unstage myfile.txt

git config --global alias.tree    ‘log  --graph  --decorate  --pretty =oneline’
now use this alias as
git tree



To remove alias
git config --global --unset alias.cm

git diff master..mybranch       (to see the changes)


git  pull  --rebase  origin
To pull all remote changes but baseline them before your local changes, so your local changes move on top of what everybody else has already committed.


git clone  --branch   xyz   url
to clone a specific Tag ‘xyz’ from a remote repo.


To unstage a file
git reset  HEAD  [filename]
It will bring back the file in the unstaged state by removing it from index/staging


git reset --hard  HEAD
It will go back to initial state by losing all the changes in the working directory.


Another way to unstage a file is by using   “git rm ” command. 
use  “--cached” option with “git rm” if want to preserve the file on our local folder.

--cached option removes file from the index/staging area , and not from the file system of the computer.

CTM: Remember that “git rm “ is used to remove the file from index.  So, if we use the git rm command on an already committed file, then we are actually marking it for deletion next time.   So the next commit will delete that file.





For merging, First we have to checkout the branch into which we want to merge the other branch.
To checkout the previous branch we were in , we can simply use the
git checkout --
ie. we don’t have to type the branch’s name again. and after checking out to that branch, we can use
git merge  [branchNameWhichWeWantToMerge]



Fork is not a git feature, but a GitHub invention.
When we fork a repo on GitHub, we get a server-side clone of repository on our GitHub account. Now
If you clone your forked repository on to your local computer, then in the remote list of your local repository, you would find the ‘origin’ alias that points to your github account’s forked repository,    Whereas, The original repository from which you have forked, will assume the alias of ‘UPSTREAM’. But this upstream alias does not get set automatically, we have to set it manually.
      git  remote  add  upstream   url

Now our local repo can be in sync with the ’remote upstream’ and ‘origin’ aliases.
Simply pull from the upstream and merge those changes in your local repository, and then push them into your origin remote.
For contribution to the upstream repo, we have to create a pull request bcoz we cannot push directly to the upstream remote if we not a contributor of the original project.



Tracing changes in file : To view last modifications made in a file.
> git blame [filename]
and then use the commit hash to view the changes
> git show  <commithash>
or
>git gui blame  myfile.txt


Bare repositories are repos that do not contain working copy files but contain only the .git folder.  A bare repository is essentially for sharing.
To setup a bare repo we use
>git init --bare  NewRepo.git
Here we are using the .git extention in repository name which is not mandatory but it a  common way to identity bare repositories.

A regular repository can be converted to a bare repository by using
>git clone --bare  myrepo    myrepo.git
By this, we have a  1:1  copy of our repo, but in a bare version & ready to be shared.

 

Backup Repository : There exists two commands for this

1.   Archive
  It archives only the files without including the versioning information. It can also archive files including in a branch, or even in a single commit. eg.
 
   git  archieve  master  --format=zip     --output=../repobak.zip
 
And to archive only the last commit, we use
    git archive  HEAD   --format=zip    --output=../headbackup.zip

 Archiving files in this way is useful if we have to share our code with people that don’t have Git installed.
 
2.   Bundle : It backups the entire repository into a  bundle including the versioning information. With git bundle, we can export a snapshot from your repository , and we can then restore it.  For eg. say, we want to clone our repository on another computer and the network is down, then in this case, we can create a bundle file of master branch of our repository.
   
  git bundle   create   --/myrepo.bundle   master

Now, we can restore this bundle in other computers like this

> cd /othercomputer/Folder

> git clone  myrepo.bundle   testreponame   -b  master

 
 
























































0 comments:

Post a Comment

Twitter Delicious Facebook Digg Stumbleupon Favorites More