Git Command Examples
- Checkout a Remote Branch in Local
- Print the Short Commit SHA1 of a Git Tag
- Fix the
^M
Character Shown ingit diff
Result - Prune stale remote branches in local repository
Checkout a Remote Branch in Local
$ git checkout --track origin/master
The above command creates a local branch with the same name, i.e. master
, as the remote branch,
and let the local branch track the remote one.
“Tracking” means when run git push
, Git knows where it pushes changes into.
Some notes from git checkout --help
,
As a convenience, –track without -b implies branch creation
-t, –track
When creating a new branch, set up “upstream” configuration.
If no -b option is given, the name of the new branch will be derived from the remote-tracking branch
Print the Short Commit SHA1 of a Git Tag
# Assume the Git tag is "0.1.0"
$ git rev-list -n 1 0.1.0 --pretty=format:"%h" | tail -1
c363005
The tag “0.1.0” points to the commit c363005
.
Use %H
if the full SHA1 is needed.
(Search “placeholder” in git show --help
for the document of format:<string>
.)
Add --abbrev
option, like --abbrev=8
, if a fixed width SHA1 is needed.
Fix the ^M
Character Shown in git diff
Result
Sometimes, when run git diff
, it prints ^M
at the end of some lines.
The ^M
character represents a carriage-return character, i.e. CRLF
, the new line character in Windows.
You may see ^M
before, if you use Vim to edit some files coming for Windows/DOS.
Seeing ^M
in the git diff
result means the same line was ended with CRLF
but now
with LF
, or vice versa.
Usually, a Git repository should be configured in a way that all text files committed
into the repository end with LF
, while files checked out end the local machine specific
endings, i.e. LF
in Unix and CRLF
in Windows machines. So that ^M
would not be seen
in git diff
. To fix a repository’s configuration, add a .gitattributes
file with content
like
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
# Declare files that will always have CRLF line endings on checkout.
*.bat text eol=crlf
“Renormalize” all the files with updated configuration.
$ git stash -u
$ git add --renormalize .
$ git status
$ git commit -m "Normalize line endings"
$ git stash pop
See this GitHub doc, Configuring Git to handle line endings, for more details.
Prune stale remote branches in local repository
As time goes by, local repository may have many remote branches, which were actually
deleted in remote repository. For example, in GitLab someone’s feature branch is usually
deleted while it’s merged by a merge request. However, these origin/feat-x
,
origin/feat-y
branches are kept in your local repository since they’re fetched.
To delete these stale remote branches in local all at once, run
$ git remote prune origin
# Or,
$ git fetch --prune
It’s said in git remote --help
,
might even prune local tags that haven’t been pushed there.
So it’s a good idea to run above commands with --dry-run
option first.
Delete one remote branch by git branch -r -d origin/feat-x
.
Avoid Wrong Tracking When Create Branches in Git
Just made a mistake to push commits to a wrong remote branch. Below is the detail.
- Need to create a new branch
br-x
, which needs to be based on the newest remotedev
branch. - Run
git fetch
to get newest change from the remote. - Run
git checkout -b br-x origin/dev
to create branchbr-x
. - Change and commit files in branch
br-x
. - Run
git push origin -u br-x
to push commits to the remote.
In step 3, the origin/dev
is used to as the “start-point” of the new br-x
branch. As per git branch --help
,
When a local branch is started off a remote-tracking branch, Git sets up the branch (specifically the
branch.<name>.remote
andbranch.<name>.merge
configuration entries) so that git pull will appropriately merge from the remote-tracking branch. This behavior may be changed via the global branch.autoSetupMerge configuration flag.
In other words, the git checkout -b br-x origin/dev
not only create a new br-x
branch, but also let the br-x
track
the remote dev
branch. As a result, in step 5, the git push origin -u br-x
doesn’t push commits into a same-name remote branch.
However, it pushes commits into the remote dev
branch, which the local br-x
is tracking since its creation.
The remote dev
branch is accidentally modified. 😞
To avoid it, one method is use the local dev
branch as the “start-point” in step 3. Consider the local dev
may be behind
the remote dev
. You may have to switch to the local dev
and git pull
to update it first.
Another method is using --no-track
option, i.e. git checkout -b --no-track br-x origin/dev
.
A more thorough method is using git config --global branch.autoSetupMerge false
to change the default behavior of Git.
When branch.autoSetupMerge
is false
, when create a branch, Git will not setup its tracking branch even if the “start-point” is a remote-tracking branch.
From more details search “branch.autoSetupMerge” in git config --help
.
For what is “remote-tracking” branch, check this link. Simply put,
Remote-tracking branch names take the form
<remote>/<branch>
.
Different Emails Addresses for Different Git Repositories
Sometimes, we may want to set up different user emails and user names for different Git repositories.
For example, in your personal computer, the user.email
is set to your personal email address globally.
While committing to your corporate repositories in the personal computer, your corporate email address should be used in the
commits. Or you’re working on personal projects on the corporate computer, need to use the personal email for the personal
repositories.
Configure Email Address for A Repository
The simplest way is going to each repository, and configuring the user email for each repository specifically.
$ cd /path/to/repo-foo
$ git config user.email email.foo@example.com
$ git config user.name name-foo
The above git config
commands write the user.email
setting into the .git/config
file under the repository.
From git help config
, when writing configuration, by default it’s writing to the repository-local configuration file.
When writing, the new value is written to the repository local configuration file by default, and options –system, –global, –worktree, –file
can be used to tell the command to write to that location
Examine the Email Address for a Repository
$ cd /path/to/repo-foo
$ git config --list | grep user.email
user.email=email.bar@example.com
user.email=email.foo@example.com
The git config --list
above prints more than one user.email
values. It’s because, without additional options, the
git config --list
outputs configuration “merged” from system, global and local.
From git help config
,
When reading, the values are read from the system, global and repository local configuration files by default
The git config --list
is a read operation.
The first user.email
value above is from “global”, i.e. ~/.gitconfig
.
Run git config --list --local | grep user.email
to check the repository-local email configuration.
Instead of piping config --list
and grep
, use git config --get user.email
to save some typings.
$ cd /path/to/repo-foo
$ git config --get user.email
user.email=email.foo@example.com
From git help config
, --get
returns
the last value if multiple key values were found.
Here, the last value is the email from repository-local configuration.
The --get
can be further omitted, git config user.email
has the same result.
And git config --get-all user.email
is same as git config --list | grep user.email
.
Conditional Includes
For new cloned repositories, it’s often to forget to configure the right email addresses for them.
The “conditional includes” feature of the git config
can save us from this problem.
For example, in your personal computer, all corporate repositories are under ~/corp-repo/
.
Add a text file called corp-gitconfig
there, and edit it as below.
[user]
name = user-name-for-corp-prj
email = email-add@your-corp.com
Add below lines in the global git config file, i.e. ~/.gitconfig
.
[includeIf "gitdir:~/corp-repo/"]
path = ~/corp-repo/corp-gitconfig
Now if a new repository is cloned user ~/corp-repo/
, the email for that repository is automatically set to
email-add@your-corp.com
.
Git in 2016
这篇文章回顾了Git的一些新功能。
Worktree
通过git worktree
,一个Git repository可以有多个工作目录。
如果一段时间内,需要同时工作在一个repository的多个分支上,那么使用worktree比反复切换branch要方便。
$ git worktree add -b hotfix/BB-1234 ../hotfix/BB-1234
Bisect
git bisect
不是一个特别新的功能。用它方便地定位出问题的commit(假设test case充足的话)。
$ git bisect start
$ git bisect good v2.0.0
$ git bisect bad master
$ git bisect run npm test
Autostash
$ git config --global rebase.autostash true
这样就不怕每次rebase前忘记git stash
了。
Simple Stash IDs
不需要输入git stash apply stash@{n}
,简单地输入git stash apply 1
就可以了。
更多的内容,请阅读原文。