git 常用命令
工作中使用 git 也有些时间了,赶脚 git 非常好用,忍不住赞叹。这里记录下平时工作中常用或偶尔会使用的一些命令,主要也是便于自己随时查询。
GIT config 配置
主要配置
git config --list #查看git设置
git config --global --list #如果查看global的设置,
git config --global -l #如果查看global的设置,
git config --global user.name youName #设置全局用户名
git config --global user.email youName@email.com #设置优先
git config --global core.editor vim #git 配置编辑方式
git config --global --edit #git 配置修改
git config --global core.quotePath false #解决中文乱码
其他辅助配置
git config -e --global #会打开~/.gitconfig文件
git config -e --system #会打开/etc/gitconfig文件
用下面的命令:
git config branch.dev.rebase true #给git pull加上默认rebase功能,已经创建好的分支还是需要手动配置
git config --global branch.autosetuprebase always #所有的分支都应该用rebase
log 操作命令
git log --graph #以图形模式显示
git log --stat #显示文件更改列表
git log --author= 'name' #显示某个作者的日志
git log -p <filepath> #查看某个文件的详细修改(显示每次提交的diff)
git log -L start,end:filepath #查看某个文件某几行范围内的修改记录
git log --stat <commit-SHA> #查看某一次提交的文件修改列表
git show --stat <commit-SHA> #查看某一次提交的文件修改列表
status 文件状态
首先要明白文件有几种状态,最重要的是理解 【暂存区】,这也算是 git 一大优势。
常用命令只有下面这一个
git status
stash 操作命令
stash 可以非常方便的帮你保存当前 Working Copy 的状态,然后转到其他的clean Working Copy。实在是非常好用。唯一注意的是,一定记得添加一些辅助信息,而且是用后即焚(程序员很难记得一个月前执行 git stash 时存了什么数据在里面)。
git stash 后面都是可以携带 @{num} 参数,表示第 num 个 存储。
git stash save "current state message" #强烈推荐,执行存储时,添加备注,方便查找
git stash list #查看stash存储列表,最好不要超过3个,否则谁记得都收藏了什么
git stash show #默认显示最近一个存储做了哪些改动
git stash show -p #默认查看stash最近一个存储列表的改动,
git stash apply #默认应用第一个存储列表,即stash @{0}
git stash pop #默认应用后,并删除第一个存储列表
git stash apply stash@{$num} #应用第二个存储列表后,并删除第二个存储列表
git stash drop stash@{$num} #丢弃stash@{$num}存储,从列表中删除这个存储
git stash clear #删除所有缓存的stash
此外,如果当前新增加了文件还没有执行add 操作,而你也需要存储 untracked files 时, 需要执行命令如下:
git stash -u # [-u|--include-untracked] ,包含untracked files 也存贮起来。
git stash apply --index #除了恢复工作区的文件外,还尝试恢复暂存区
diff 操作命令
git diff filePath #工作区与暂存区比较
git diff HEAD filePath #工作区与HEAD ( 当前工作分支) 比较
git diff --cached #filepath 暂存区与HEAD比较,和下面命令等效
git diff --staged #filepath 暂存区与HEAD比较,和上面命令等效
git diff branchName filePath #当前分支的文件与branchName 分支的文件进行比较
git diff <commit-SHA> filepath #与某一次提交进行比较
branch 分支
git 区别于 svn 一个很重要的特性,除了分布式外,还增加对多个 branch 的支持。你可以很方便的从一个工作的 branch 切换到另外一个,执行一些操作后,返回当前 branch ,并进行一些相关操作。
git branch #查看本地有哪些分支;
git branch -va #查看所有分支目前的<commit-SHA>,包含本地分支和远程分支;
git branch -v #查看本地所有分支目前的<commit-SHA>;
git branch -a #查看所有分支,包含本地分支和远程分支
git branch <branchName> <commit-SHA> #基于<commit-SHA> 创建一个新的分支branchName;
git stash <branchName> #从最新的stash创建分支
checkout 切换分支
checkout 除了可以切换分支,还还可以新建分支,或者放弃对当前某个文件代码修改,回退到未修改状态。
git checkout <branchName> #从当前分支切换到 <branchName>
git checkout -b <newBranchName> #基于当前分支,新建一个<newBranchName>
git checkout -- <fileName> #放弃对<fileName>的修改
git checkout -- . #放弃对所有Modify的修改
rebase/merge 同步分支
git rebase 和 git merge 都可以完成多个分支之间的合并操作,相比较而言,推荐 rebase(会将 branchName 的多次提交,包含多次提交状态和 log 原样拷贝到当前分支),少用 merge(git merge 默认是按照 时间先后顺序排布,如若本机和服务器时间不同步,本次提交 log 在服务器版本显示的先后顺序将无法确定),因为底层实现机制不同,这里不多做介绍,网上有很多讲解。
git rebase <branchName> #将 branchName 上的(一次或多次)提交同步到当前分支;
git cherry-pick <commit-SHA> #只合并某次提交<commit-SHA>的内容;
若多次临时提交想合并成一次正式提交,推荐使用下面的命令,常用而且好用。
git rebase -i <commit-SHA> #非常有用,将一个branch多次提交合并为一次,<commit-SHA>必须是待合并的前一次提交;
使用 git merge 命令,总是会出现一行 merge 命令操作,而又没有任何的意义在里面,因此对强迫症患者的程序员,为了 log 看起来更加美观,个人在使用 merge 操作时,一般操作步骤如下:
#与rebase功能等价,只是将<branchName>分支修改的多个<commit-SHA> 当作diff 文件,一次性和并到【当前分支】
#下面两个步骤要一起执行,才算是完成一次完整的代码合并操作。
git merge <branchName> --no-commit --squash #只是合并代码,但是并未commit
git commit -F comments.txt #重新填写log 并完成 commit
push/pull 操作
注意:与远程分支的操作,只有push/pull 操作,其他命令都是在本地 Working Copy 完成的。
git pull #更新本地与 <remoteName> 对应的所有 branch.
git pull --rebase <remoteName> #将远程分支更新到本地.
git pull --rebase origin/<remoteBranch> #代码提交前的必要操作,将远程<remoteBranch>分支更新到本地.
git push origin <remoteName> #将本地提交,push到远程分支.
git push <remoteName> --delete <remoteBranch> #将remote(如origin)的远程分支删除.
git remote update -p #若远程分支删除失败,则更新所有的远程分支。
git push -f origin <remoteBranch> #慎用!!!将本地分支强制推送到远程分支(即使与远程分支不同)
reset 操作命令
“–hard” 和 “–soft” 要注意区分差异。默认是 “–mixed”(So,省去你记忆)。
- “–hard” ,经常使用,工作区和暂存区内容全部改变;
- “–soft” ,较少使用,不会改变工作区和暂存区的内容(即上次提交代码的所有修改都在,不会直接丢弃);除非是想撤回本次提交中个别文件,同时只提交部分文件,配合 git checkout – 使用。
git reset #回退到暂存区之前的状态,但是Working Copy 的状态并没有改变。
# 这里 ^^^ 和 ~3 是等价的,看个人喜好
git reset --hard HEAD^ #回退到上一个提交的版本,即放弃所有修改到【Modified】(Changes not staged for commit)状态;
git reset --hard HEAD^^^ #回退到倒数第三个提交的版本;
git reset --hard HEAD~1 #等价命令回退到上一个提交的版本,放弃所有修改到【Modified】(Changes not staged for commit)状态;
git reset --hard HEAD~5
git reset --soft HEAD^ #常用于撤回本次commit,但是所有修改依然保留
commit 操作
git commit -m "deliver message log" #
git commit -F comments.txt #
git commit --amend #修改最后一次提交的 log
reflog
这世间还真有卖“后悔药”的,其中 reflog 算一个,谁用谁知道。
一般配合 git reset 使用。
git reflog #记录本地执行的 all 有效操作,方便你随时回滚
git reset --hard <reflog-SHA> #回滚到 reflog 中某次操作之前的状态。
remote
任意两台主机之间想同步分支,其中一台需要先添加另一台电脑的(远程)信息。
git remote add <remoteName> <user>@<IpAdress>:<path> #本地新建远程分支<remoteName>
git pull <remoteName> #更新刚刚建立的 <remoteName> 对应的 branch
git remote rm <remoteName> #删除远程分支<remoteName>
#当出现 error: unable to delete 后者是 error: failed to push some refs to
git remote update --prune #更新所有的远程分支
git remote update --p #和上面的--prune命令等价
若出现
“remote:error:refusing to update checked out branch:refs/heads/leiminLocal”
的解决办法:remoteName 一端必须得使用下面2个命令才能看到push后的内容。
git config denyCurrentBranch false #仅执行一次;
git reset --hard #后续每次push 都需要执行;
根本解决措施是,在建立新库的时候,要添加 --bare 选项。具体差异常见引用部分。
git --bare init
在初始化远程仓库时最好使用 git –bare init 而不要使用:git init。这样在使用hooks的时候,会有用处。
如果使用了 git init 初始化,则远程仓库的目录下,也包含 work tree,当本地仓库向远程仓库push时, 如果远程仓库正在push的分支上(如果当时不在push的分支,就没有问题), 那么push后的结果不会反应在 work tree 上, 也即在远程仓库的目录下对应的文件还是之前的内容,必须得使用 git reset –hard 才能看到push后的内容。
Patch 相关操作命令
生成 Patch 文件命令
git format-patch #生成 patch 文件
git format-patch HEAD^ #生成最近的1次commit的patch
git format-patch HEAD^^ #生成最近的2次commit的patch
git format-patch HEAD^^^ #生成最近的3次commit的patch
git format-patch HEAD^^^^ #生成最近的4次commit的patch
git format-patch <r1>..<r2> #生成两个commit间的修改的patch(包含两个commit. <r1>和<r2>都是具体的commit号)
git format-patch -1 <r1> #生成单个commit的patch
git format-patch <r1> #生成某commit以来的修改patch(不包含该commit)
git format-patch --root <r1> #生成从根到r1提交的所有patch
打 Patch 命令有两种方式,分别是 git apply 和 git am:
git apply --stat 0001-limit-log-function.patch # 查看patch的情况
git apply --check 0001-limit-log-function.patch # 检查patch是否能够打上,如果没有任何输出,则说明无冲突,可以打上
git am 0001-limit-log-function.patch # 将名字为0001-limit-log-function.patch的patch打上
git am --signoff 0001-limit-log-function.patch # 添加-s或者--signoff,还可以把自己的名字添加为signed off by信息,作用是注明打patch的人是谁,因为有时打patch的人并不是patch的作者
git am ~/patch-set/*.patch # 将路径~/patch-set/*.patch 按照先后顺序打上
git am --abort # 当git am失败时,用以将已经在am过程中打上的patch废弃掉(比如有三个patch,打到第三个patch时有冲突,那么这条命令会把打上的前两个patch丢弃掉,返回没有打patch的状态)
git am --resolved #当git am失败,解决完冲突后,这条命令会接着打patch
注意:git apply 与 git am 的区别是:
-
git apply 并不会将 commit message 等信息附带上去,打完 patch 后需要重新 git add 和 git commit ;
-
git am 会直接将patch的所有信息打上去,而且不用重新 git add 和git commit,author也是 patch 的 author 而不是打 patch 的人。
参考
ProGit
git init 和git –bare init 的具体区别
Git忽略提交规则 - .gitignore配置运维总结