时间 | 更新备注 |
---|---|
2018-02-28 | 新建文章 |
2018-06-08 | 整理补充 |
2019-01-18 | 更新链接 |
目录
- Git 笔记系列(一)—— Git简介
- Git 笔记系列(二)—— Git工作流程
- Git 笔记系列(三)—— Git常用命令-一览
- Git 笔记系列(四)—— Git常用命令-Checkout
- Git 笔记系列(五)—— Git常用命令-Branch
- Git 笔记系列(六)—— Git常用命令-Reset
- Git 笔记系列(七)—— Git常用命令-Rebase
- Git 笔记系列(八)—— Git常用命令-Stash等
- Git 笔记系列(九)—— Git进阶
Git 命令图解
命令
- workspace: 本地的工作目录。(记作A)
- index:缓存区域,临时保存本地改动。(记作B)
- local repository: 本地仓库,只想最后一次提交HEAD。(记作C)
- remote repository:远程仓库。(记作D)
以下所有的命令的功能说明,都采用上述的标记的A、B、C、D的方式来阐述。
初始化
git init //创建
git clone /path/to/repository //检出
git config --global user.email "you@example.com" //配置email
git config --global user.name "Name" //配置用户名
操作
git add <file> // 文件添加,A → B
git add . // 所有文件添加,A → B
git commit -m "代码提交信息" //文件提交,B → C
git commit --amend //与上次commit合并, *B → C
git push origin master //推送至master分支, C → D
git pull //更新本地仓库至最新改动, D → A
git fetch //抓取远程仓库更新, D → C
git log //查看提交记录
git status //查看修改状态
git diff //查看详细修改内容
git show //显示某次提交的内容
撤销操作
git reset <file>//某个文件索引会回滚到最后一次提交, C → B
git reset//索引会回滚到最后一次提交, C → B
git reset --hard // 索引会回滚到最后一次提交, C → B → A
git checkout // 从index复制到workspace, B → A
git checkout -- files // 文件从index复制到workspace,用来丢弃本地修改, B → A
git checkout HEAD -- files // 文件从local repository复制到workspace, C → A
分支
git checkout -b branch_name //创建名叫“branch_name”的分支,并切换过去
git checkout master //切换回主分支
git branch -d branch_name // 删除名叫“branch_name”的分支
git push origin branch_name //推送分支到远端仓库
git merge branch_name // 合并分支branch_name到当前分支(如master)
git rebase //衍合,线性化的自动, D → A
冲突处理
git diff //对比workspace与index
git diff HEAD //对于workspace与最后一次commit
git diff <source_branch> <target_branch> //对比差异
git add <filename> //修改完冲突,需要add以标记合并成功
git reset
详细见Git 笔记系列(五)—— Git常用命令-Reset
重置命令(git reset
)是Git
最常用的命令之一,也是最危险,最容易误用的命令。来看看git reset
命令的用法。
用法一:git reset [-q] [<commit>] [--] <paths>...
用法二:git reset [--soft | --mixed | --hard | --merge | --keep] [-q] [<commit>]
上面列出了两个用法,其中<commit>
都是可选项,可以使用引用或者提交ID
,如果省略 <commit>
则相当于使用了HEAD
的指向作为提交ID
。
上面列出的两种用法的区别在于,第一种用法在命令中包含路径<paths>
。为了避免路径和引用(或者提交ID
)同名而冲突,可以在<paths>
前用两个连续的短线(减号)作为分隔。
第一种用法(包含了路径<paths>
的用法)不会重置引用,更不会改变工作区,而是用指定提交状态(<commit>
)下的文件(<paths>
)替换掉暂存区中的文件。例如命令git reset HEAD <paths>
相当于取消之前执行的git add <paths>
命令时改变的暂存区。
第二种用法(不使用路径<paths>的用法)则会重置引用。根据不同的选项,可以对暂存区或者工作区进行重置。参照下面的版本库模型图,来看一看不同的参数对第二种重置语法的影响。
git reflog
如果没有记下重置前master
分支指向的提交ID,想要重置回原来的提交真的是一件麻烦的事情(去对象库中一个一个地找)。幸好Git
提供了一个挽救机制,通过.git/logs
目录下日志文件记录了分支的变更。默认非裸版本库(带有工作区)都提供分支日志功能,这是因为带有工作区的版本库都有如下设置:
$ git config core.logallrefupdates
true
查看一下master
分支的日志文件.git/logs/refs/heads/master
中的内容。下面命令显示了该文件的最后几行。为了排版的需要,还将输出中的40位的SHA1
提交ID缩短形式。
$ tail -5 .git/logs/refs/heads/master
dca47ab a0c641e Jiang Xin <jiangxin@ossxp.com> 1290999606 +0800 commit (amend): who does commit?
a0c641e e695606 Jiang Xin <jiangxin@ossxp.com> 1291022581 +0800 commit: which version checked in?
e695606 4902dc3 Jiang Xin <jiangxin@ossxp.com> 1291435985 +0800 commit: does master follow this new commit?
4902dc3 e695606 Jiang Xin <jiangxin@ossxp.com> 1291436302 +0800 HEAD^: updating HEAD
e695606 9e8a761 Jiang Xin <jiangxin@ossxp.com> 1291436382 +0800 9e8a761: updating HEAD
可以看出这个文件记录了master
分支指向的变迁,最新的改变追加到文件的末尾因此最后出现。最后一行可以看出因为执行了git reset –hard
命令,指向的提交ID
由e695606
改变为9e8a761
。
Git
提供了一个git reflog
命令,对这个文件进行操作。使用show
子命令可以显示此文件的内容。
$ git reflog show master | head -5
9e8a761 master@{0}: 9e8a761: updating HEAD
e695606 master@{1}: HEAD^: updating HEAD
4902dc3 master@{2}: commit: does master follow this new commit?
e695606 master@{3}: commit: which version checked in?
a0c641e master@{4}: commit (amend): who does commit?
使用git reflog
的输出和直接查看日志文件最大的不同在于显示顺序的不同,即最新改变放在了最前面显示,而且只显示每次改变的最终的SHA1
哈希值。还有个重要的区别在于使用git reflog
的输出中还提供一个方便易记的表达式:<refname>@{<n>}
。这个表达式的含义是引用<refname>
之前第<n>
次改变时的SHA1
哈希值。
那么将引用master
切换到两次变更之前的值,可以使用下面的命令。
重置master
为两次改变之前的值。
$ git reset --hard master@{2}
HEAD is now at 4902dc3 does master follow this new commit?
重置后工作区中文件new-commit.txt
又回来了。
$ ls
new-commit.txt welcome.txt
提交历史也回来了。
$ git log --oneline
4902dc3 does master follow this new commit?
e695606 which version checked in?
a0c641e who does commit?
9e8a761 initialized.
此时如果再用git reflog
查看,会看到恢复master的操作也记录在日志中了。
$ git reflog show master | head -5
4902dc3 master@{0}: master@{2}: updating HEAD
9e8a761 master@{1}: 9e8a761: updating HEAD
e695606 master@{2}: HEAD^: updating HEAD
4902dc3 master@{3}: commit: does master follow this new commit?
e695606 master@{4}: commit: which version checked in?
git remote
- 添加远程库:
$ git remote add origin
- 移除远程库:
$ git remote remove (OrignName)
- 查看远程库:
$ git remote -v
(--verbose)
git grep查找
git grep -n "要查找的字符串"
- -W 查找函数上下文
- 使用 --count 参数, 只会显示在哪个文件里有几个要查找的字符串, 如下:
git grep --count "(defun format "
src/format.lisp:1
可以使用 $ git help grep
来查看帮助
Git 其他常用命令
Git undo撤销方法
git revert <SHA>
git commit --amend -m "Modify last add message"
- 撤销本地的修改
git checkout -- <bad filename>
- 重置本地的修改
git reset <last good SHA>
Git Merge
使用Xcode
的FileMerge
合并代码
# Tell system when Xcode utilities live:
sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer
# Set "opendiff" as the default mergetool globally:
git config --global merge.tool opendiff
- 代码冲突
! [rejected] master -> master (non-fast-forward)
的原因以及解决办法:
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'git@github.com:archermind/LEDTorch.apk-for-Android.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again. See the 'Note about
fast-forwards' section of 'git push --help' for details.
操作命令:
- 正确的做法是,在
push
之前git fetch origin
,将github
上的新代码拉下来,然后在本地merge
,如果没有冲突就可以push了,如果有冲突的话要在本地解决冲突后,再pus
h。具体做法就是:
git fetch origin
git merge origin (master)
- 这两步其实可以简化为
git pull origin master
git-fetch - Download objects and refs from another repository
git-merge - Join two or more development histories together
Git log
Table 3. 限制 git log 输出的选项
选项 说明
-(n)
仅显示最近的 n 条提交
--since, --after
仅显示指定时间之后的提交。
--until, --before
仅显示指定时间之前的提交。
--author
仅显示指定作者相关的提交。
--committer
仅显示指定提交者相关的提交。
--grep
仅显示含指定关键字的提交
-S
仅显示添加或移除了某个关键字的提交
来看一个实际的例子,如果要查看 Git 仓库中,2008 年 10 月期间,Junio Hamano 提交的但未合并的测试文件,可以用下面的查询命令:
$ git log --pretty="%h - %s" --author=gitster --since="2008-10-01" \
--before="2008-11-01" --no-merges -- t/
5610e3b - Fix testcase failure when extended attributes are in use
acd3b9e - Enhance hold_lock_file_for_{update,append}() API
f563754 - demonstrate breakage of detached checkout with symbolic link HEAD
d1a43f2 - reset --hard/read-tree --reset -u: remove unmerged new paths
51a94af - Fix "checkout --track -b newbranch" on detached HEAD
b0ad11e - pull: allow "git pull origin $something:$current_branch" into an unborn branch
在近 40000 条提交中,上面的输出仅列出了符合条件的 6 条记录。
- 显示每次提交的diff:
git log -p
- 按成员的提交历史
git shortlog
- 在提交的历史改动中查找关键字,
-p
代表显示log提交的改动
git log -S"searchKeyWord" -p
5, 搜索提交的注释
git log --grep=“keyWord”
- 搜索某个用户的提交
git log --author=“authorName”
Git diff
通过使用不同的参数调用git diff
命令,可以对工作区、暂存区、HEAD
中的内容两两比较。下面的这个图,展示了不同的git diff命令的作用范围。
diff: 分支点之间的变化
分支点的继承
当add了change后,
git diff
是不会显示已经add后的change的,可以制定stage的diff
git diff --staged
Git 比较不同版本文件差异的常用命令格式:
git diff 查看尚未暂存的文件更新了哪些部分
git diff filename 查看尚未暂存的某个文件更新了哪些
git diff –cached 查看已经暂存起来的文件和上次提交的版本之间的差异
git diff –cached filename 查看已经暂存起来的某个文件和上次提交的版本之间的差异
git diff ffd98b291e0caa6c33575c1ef465eae661ce40c9 b8e7b00c02b95b320f14b625663fdecf2d63e74c 查看某两个版本之间的差异
git diff ffd98b291e0caa6c33575c1ef465eae661ce40c9:filename b8e7b00c02b95b320f14b625663fdecf2d63e74c:filename 查看某两个版本的某个文件之间的差异
Git config
Git的配置
- 列出
Git
全局配置列表
git config --global --list
- 列出
Git
本地仓库配置列表
git config --local --list
- 设置用户名,邮箱密码等
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com
- 设置编辑器
$ git config --global core.editor emacs
设置git
命令 别名
$ git config --global alias.st status
$ git config --global alias.co checkout
$ git config --global alias.ct commit
$ git config --global alias.df diff
$ git config --global alias.br branch
#git lg to view commit log like network graph
$ git config --global alias.lg "log --all --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%ci) %C(bold blue)<%an>%Creset' --abbrev-commit"
Git命令的别名
有些Git
的命令很长,如果经常输入就很繁琐,通过设置Git
的别名,可以简化输入,提交效率,这里推荐一个Git
的别名库,方便使用各种Git
命令。
git-extras/Commands.md at master · tj/git-extrasGIT utilities -- repo summary, repl, changelog population, author commit percentages and more
同一台电脑可以有2个git账号(不同网站的)
这种情况下,需要几点注意
1.remote pull push
的时候有问题,因为要设置邮箱问题了 pull的时候识别的是邮箱,2个github账号,2个邮箱,我们自然不能使用global的user.email了
1.取消global
git config --global --unset user.name
git config --global --unset user.email
2.设置每个项目repo的自己的user.email
git config user.email "xxxx@xx.com"
git config user.name "suzie"
之后push pull
就木有问题了
备注
生成ssh key
ssh-keygen -m rsa -C "your mail
(当前目录) 然后可以命名默认id_rsa
或者id_rsa_second
把对应的pub放到公共服务器上。
其他
gitk //开灯图形化git
git config color.ui true //彩色的 git 输出
git config format.pretty oneline //显示历史记录时,每个提交的信息只显示一行
git add -i //交互式添加文件到暂存区
常见命令菜单
Git Cheat Sheet Part1
看了前面那么多命令,是不是有点多了?ㄟ( ▔, ▔ )ㄏ平时开发用的到那么多命令吗?Don`t worry,常用的命令只需看下面几张图即可: