Hi there!
Recently, I've spent some time to organize my git commands notes. I know you can find those commands online easily, but I would like to share these what I think useful and put them together here for my own references. Let's take a look!
General Settings
- Setting Editor for git. This would be useful when writing Commit Messages. When committing changes without specifying a message inline (using
git commit -m "message"
), git opens the default editor to let you write a commit message. Without a predefined editor, it might not know which text editor to open, especially when you have your own preferences for editing messages.
In my case, I like vim, so here comes how I set it. Simple.
git config --global core.editor "vim"
- Setting Committer Name & Email Globally. Of course, this is a must.
git config user.name "your name" git config user.email "your_email@email.com"
- If you want to apply Committer Name & Email per repository, just simply omit the --global flag from above commands and run it from your repository folder.
- Changing the Author Information Just for the Next Commit
git commit --author="your name <your_email@email.com>"
- Show all commiter/author in log
git log --pretty="%an %ae%n%cn %ce" | sort | uniq
%an author name %ae author email %n new line %cn committer name %ce committer email
You will notice that, for each commit, it has both author name and committer name.
Branches
Operations | Command |
---|---|
Get current working branch | git branch |
Checkout specific branch | git clone -b specific_branch --single-branch http://username@192.168.99.100:8080/scm/your-repo.git |
Create a branch | git checkout -b new_branch |
Push to remote branch | git push origin remote_branch |
Delete local branch | git branch -d <branch> |
Delete remote branch | git push origin :[name_of_your_new_branch] |
Notes:
- "git branch <branch_name>" : The repository history remains unchanged. All you get is a new pointer to the current commit.
- The "git branch <branch_name>" only creates the new branch. To start adding commits to it, you need to select it with git checkout, and then use the standard git add and git commit commands.
- Delete branch: "-d" is a “safe” operation in that Git prevents you from deleting the branch if it has unmerged changes. The only difference is the ":" to say delete, you can do it too by using github interface to remove branch : https://help.github.com/articles/deleting-unused-branches.
Fast-forward merge
- Start a new feature
git checkout -b new-feature master
- Edit some files
git add <file> git commit -m "Start a feature"
- Edit some files
git add <file> git commit -m "Finish a feature"
- Merge in the new-feature branch
git checkout master (This will switch to master branch) git merge new-feature (This will merge your changes from new-feature branch to master) git branch -d new-feature
Git Clone
Clone into current directory
git init . git remote add origin <repository-url> git pull origin master
Git Checkout
Check out files deleted locally
Sometimes, you might accidently delete some files in your local repos. Then you can use below command to pull them back from remote:
git checkout HEAD <path>
Clone a subdirectory only of a Git repository
What you are trying to do is called a sparse checkout.
mkdir <repo> cd <repo> git init git remote add -f origin <https://product.git>
This creates an empty repository with your remote, and fetches all objects but doesn't check them out. Then do:
git config core.sparseCheckout true
Now you need to define which files/folders you want to actually check out. This is done by listing them in .git/info/sparse-checkout, eg:
echo "temp" >> .git/info/sparse-checkout
Last but not least, update your empty repo with the state from the remote:
git pull origin master
You will now have files "checked out" for "temp" folder on your file system, and no other paths present.
Clone specific branch of a Git repository
Just use singel-branch option:
git clone -b <branch tag> --single-branch https://user.name@product.git
Git Remote
I was wondering what is a git remote
, here is:
A remote in git is basically a bookmark for a different repository from which you may wish to pull or push code. The bookmarked repository may be on your local computer in a different folder, on remote server, or it may even be the repository itself ( I haven't tried this ) but the simplest analogy is a bookmark. The repository doesn't even have to be a version of your repository, it may even be a completely unrelated repository.
Other explanations:
As you probably know, git is a distributed version control system. Most operations are done locally. To communicate with the outside world, git uses what are called remotes. These are repositories other than the one on your local disk which you can push your changes into (so that other people can see them) or pull from (so that you can get others changes). The command git remote add origin git@github.com:peter/first_app.git creates a new remote called origin located at git@github.com:peter/first_app.git. Once you do this, in your push commands, you can push to origin instead of typing out the whole URL. Is the word 'origin` is arbitrary? Yes.
Git Log
git log -1 --graph --name-only feature/your-feature * commit d1f669674305665f9e6b8914511ed709aa8f09xb (HEAD -> feature/your-feature, origin/feature/your-feature) | Author: xx.author <xx.author@yourdomain.com> | Date: Wed Jul 26 15:14:48 2017 -0700 | | Your comments. | | your-source-code/file.sh | your-source-code/file02.sh git log -1 --graph --name-only --pretty=oneline feature/your-feature * d1f669674305665f9e6b8914511ed709aa8f0x2b (HEAD -> feature/your-feature, origin/feature/your-feature) Your comments. | your-source-code/file.sh | your-source-code/file02.sh
The log command takes a --follow argument that continues history before a rename operation:
git log --follow ./renamed_path/to/file
Git Diff
git diff HEAD your_file git diff HEAD@{1} your_file --> The @{1} means "the previous position of the ref I've specified", so that evaluates to what you had checked out previously - just before the pull. git diff HEAD^ --> This will diff all files which have been changed in previous commit.
Diff that changed between two commits
git diff --word-diff SHA1 SHA2
If you only need last commit diff with previous one:
git show
If you only need names and comments:
git show --name-only
Git Stash
Operations | Command |
---|---|
Stash | git stash |
Bring back your local changes | git stash pop |
git stash pop
throws away the (topmost, by default) stash after applying it, whereas git stash apply
leaves it in the stash list for possible later reuse (or you can then git stash drop it).
This happens unless there are conflicts after git stash pop
, in this case, it will not remove the stash, behaving exactly like git stash apply.
Another way to look at it: git stash pop
is git stash apply
&& git stash drop
.
Git Squash
Why do we need git squash and how it helps?
https://softwareengineering.stackexchange.com/questions/263164/why-squash-git-commits-for-pull-requests has collected a lot of great explanation. Among those answers, I am in more favor of this point:
Because often the person pulling a PR cares about the net effect of the commits "added feature X", not about the "base templates, bugfix function X, add function Y, fixed typos in comments, adjusted data scaling parameters, hashmap performs better than list"... level of detail
Steps:
- Set your current branch:
export curr_branch="<your_current_branch>"
git log --oneline origin/master..$curr_branch
git reset --soft `git merge-base origin/master $curr_branch`
git commit -c <hash string of one of your previous msg>
git diff HEAD <your_file>
git push --force
Revert-Reset
Undo a commit and Redo
$ git commit -m "Something comments" $ git reset HEAD~ << edit files as necessary >> $ git add ... $ git commit -c ORIG_HEAD
For the last command, if you do not need to edit the message, you could use the -C option.
Revert a commit already pushed to a remote repository
Revert with log history for tracing rollback opration
$ git revert <commit hash>
It will delete a previous commit(ab12cd15) from local branch and remote branch, but you will get a log.
Revert even without any log trace for rollback operation
You just commited a change to your local branch and immediately pushed to the remote branch. Suddenly realized , Oh no! I dont need this change. Now what can you do?
git reset --hard HEAD~1 [for deleting that commit from local branch] git push origin HEAD --force
Revise commit log
git commit --amend
Ignore local files instead of updating .gitignore
Source: https://practicalgit.com/blog/make-git-ignore-local-changes-to-tracked-files.html
git update-index --assume-unchanged <file-to-ignore>
Now you can go ahead and do whatever you want in that file and it will not show up as a changed file in git.
This will work unless that file is changed on the remote branch. In that case if you do a pull, you will get an error.
When that happens you need to tell Git to start caring about the file again, stash it, pull, apply your stashed changes, and tell Git to start ignoring the file again:
# tell Git to stop ignoring this file $ git update-index --no-assume-unchanged <file-to-ignore> # stash your local changes to the file $ git stash <file-to-ignore> # Pull from remote $ git pull # Apply your stashed changes and resolve the possible conflict $ git stash apply # Now tell Git to ignore this file again $ git update-index --assume-unchanged <file-to-ignore>
Pull latest changes from another branch to current branch
My Git Commands Alias
alias gs="git status " alias ga="git add " alias gb="git branch " alias gba="git branch -a " alias gbd="git branch -d " alias gbr="git branch -r " alias gc="git commit " alias gd="git diff " alias gco="git checkout " alias glg="git log --graph --name-only "
Q/A
Why git keep asking user credentials
Just need to run commands to store credentials into credential.helper, like this:
git config user.name "geekcoding" git config user.email "geekcoding@users.noreply.github.com" git pull <- It might ask credentails at this moment git config --global credential.helper store git config --global credential.helper cache
Seeing HEAD detached at xxxxxx
Warning:
Apparently below command will result in losing all the changes made in the detached mode. So be careful when using it.
git checkout -f master
Okay, that's all I have so far. Enjoy!