配置
  • git config --list [--system|--global|--local] 显示当前配置
  • git config [--system|--global|--local] <key> <value> 设置参数
  • git config -e [--system|--global|--local] 编辑配置
  • git config --global alias.<alias-name> "<git-command>" 创建别名
  • git <alias-name> <arguments> 使用别名
  • git config --global --unset <key> 移除单个变量
  • git config --global --unset-all <key> 移除所有变量
  • 设置例子
    # 设定身份
    git config --global user.name "cheatsheet"
    git config --global user.email "[email protected]"
    # 首选编辑器
    git config --global core.editor vim
    # 设置自动命令行着色
    git config --global color.ui auto
    #长期保存账号和密码
    git config --global credential.helper store
    
  • 别名使用例子
    # 设置别名
    git config --global alias.co checkout
    #使用别名
    git co master
    
  • 文件配置
    #本地库文件配置
    <repo>/.git/config
    #系统登录用户全局配置
    ~/.gitconfig
    #系统全局配置
    /etc/gitconfig
    
初始化
  • ssh-keygen -t rsa -C "<email-address>" 生成ssh-key
  • git init [dir] 从本地初始化
  • git init --bare [dir] 创建本地裸库
  • git clone <git-url> [dir] 从远程仓库初始化
  • git clone [--branch tag-name/branch-name] <git-url> [dir] 下载并绑定指定分支
  • git clone --bare <git-url> [dir] 克隆远程仓库裸库
  • git clone --mirror <git-url> [dir] 创建镜像仓库
  • git remote set-url <remote-host-name> <new-git-url> 修改远程仓库地址
  • 本地仓库初始化
    mkdir example
    cd example
    git init
    git remote add origin [email protected]:trensy/cheatsheet.git
    #拉取远程分支
    git pull origin master 
    #推送数据到远程分支,如果远程分支不存在则创建同名远程分支
    git push -u origin master 
    
  • 创建本地裸库
    mkdir example.git
    cd example.git
    git init --bare .
    
  • 推送到新远程仓库(1)
    git clone --bare [email protected]:trensy/cheatsheet.git
    git remote add origin [email protected]:trensy/cheatsheet_new.git 
    git push --mirror origin
    
  • 推送到新远程仓库(2)
    git clone --mirror [email protected]:trensy/cheatsheet.git
    git remote update
    git remote add origin [email protected]:trensy/cheatsheet_new.git
    git push --mirror origin
    
  • 修改远程仓库地址
    git remote set-url origin [email protected]:trensy/cheatsheet.git
    
分支(branch)
  • git branch -a 查看本地分支和远程分支
  • git branch 查看本地所有分支
  • git branch -r 查看远程所有分支
  • git branch -vv 展示本地分支关联远程仓库的情况
  • git checkout -b <branch-name> <existing-branch-name> 新建分支并切换至新分支
  • git checkout <commit-id> -b <new-branch-name> 从现有的commit创建一个新分支并切换至新分支
  • git branch [-f] <branch-name> 新建一个分支,但不切换
  • git branch [branch-name] [commit-id] 新建一个分支,指向指定commit
  • git branch <branch-name> <tag-name> 在tag的基础上新建一个分支
  • git branch <-m|-M> <old-branch-name> <new-branch-name> 重命名分支
    #不会覆盖同命名分支
    git branch -m  old-branch-name new-branch-name
    #强制重命名,会覆盖同命名分支
    git branch -M  old-branch-name new-branch-name
    
  • git branch <-d|-D> <branch-name> 删除本地分支
    #分支如果没有被合并,将删除失败
    git branch -d  branch-name 
    #分支如果没有被合并,也会删除成功
    git branch -D  branch-name
    
  • git branch <-d|-D> -r <branch-name> 删除远程分支
  • git checkout <branch-name> 切换分支
    #切换到上一个分支
    git checkout - 
    
  • 直接删除远程分支(1)
    git branch -d -r branch-name
    #别忘记提交更改到远程仓库
    git push origin :branch-name
    
  • 直接删除远程分支(2)
    git push origin --delete branch-name 
    
  • 建立分支并与远程分支关联
    git checkout -b test
    git push -u origin test
    ...
    #别忘记提交更改到远程仓库
    git push
    
标签(tag)
  • git tag 查看标签
  • git tag <tag-name> 创建命名标签
  • git tag -a <tag-name> -m <message> 添加一个注解标签
  • git tag <tag-name> <commit-id> -a -m <message> 给过去提交记录创建标签
  • git push origin <tag-name> 推送标签到远程仓库
  • git push origin --tags 推送全部标签
  • git pull origin --tags 远程拉取标签
  • git tag -d <tag-name> 删除本地标签
  • git push origin :refs/tags/<tag-name> 删除远程标签
查看
  • git status 查看变更
  • git status -s 查看变更简单模式
  • git status --ignored 展示忽略的文件
  • git log 查看日志
  • git log --oneline 单行查看日志
  • git log --stat 显示详细commit历史
  • git reflog 显示当前分支的最近几次提交
  • git log <-number> [--pretty] [--oneline] 显示过去几次提交
  • git log --follow [file] 显示文件版本历史
  • git blame [file] 显示指定文件是什么人在什么时间修改过
  • git show [--name-only] <commit-id> 显示commit内容变化
  • git show [commit-id]:[file] 显示某次提交时,某个文件的内容
  • git log --grep <keyword> 过滤&搜索
  • git log --author <author-name> 指定作者查询
  • git log --after='<date>' --until='<date>' 通过日期查找
    git log --oneline --after="2019-02-20" --until='2020-02-20'
    
  • git grep <keyword> [branch-name|tag-name] 搜索
    git grep "Hello"
    git grep "Hello" v2.5
    
  • git diff 显示暂存区和工作区的差异
  • git log -p [file] 显示指定文件相关的每一次diff
  • git diff --cached [file] 显示暂存区和上一个commit的差异
  • git diff [first-branch] [second-branch] 显示两次提交之间的差异
  • git diff HEAD 显示工作区与当前分支最新commit之间的差异
  • git shortlog -sn 显示所有提交过的用户,按提交次数排序
  • git diff --shortstat "@{0 day ago}" 显示今天你写了多少行代码
  • git log --graph --decorate --oneline 绘制分支图
本地库文件操作
  • git add <file1> <file2> ... 添加指定文件到暂存区
  • git add <dir> 添加指定目录到暂存区,包括子目录
  • git add . 提交所有修改的和新建的数据暂存区
  • git add -u 提交所有被删除和修改的文件到暂存区
  • git add -A 提交所有被删除、被替换、被修改和新增的文件到暂存区
  • git rm <file1> <file2> ... 同时从工作区和暂存区删除文件
  • git rm --cached <file1> <file2> ... 从暂存区删除文件,但是工作区文件还存在
  • git rm -r <dir-name> 删除文件夹
  • git mv <file-from> <file-to> 重命名文件,并添加新文件到暂存区
  • git stash 创建新的临时存储
  • git stash save "<stash-name>" 创建新的临时存储并命名
  • git stash -u/--include-untracked 创建新的临时存储(包含未追踪的更改)
  • git stash list 列出所有的临时存储
  • git stash show 浏览临时存储内容
  • git stash show -p 浏览临时存储差异
  • git stash pop 恢复上一个临时存储 (删除临时存储)
  • git stash apply 恢复上一个临时存储 (保留临时存储)
  • git stash apply stash@{n} 将特定的存储恢复到当前分支 (n = stash列表序号)
  • git stash <pop|apply> stash@{n} 应用特定的临时存储 (n = stash列表序号)
  • git stash drop stash@{n} 删除特定的临时存储 (n = stash列表序号)
  • git stash clear 删除所有的临时存储
  • git commit -m <message> 提交暂存区到本地仓库
  • git commit <file1> <file2> ... -m <message> 提交暂存区的指定文件到本地仓库
  • git commit -am <message> 不需要执行git add命令提交暂存区的指定文件到本地仓库,只是对修改和删除文件有效,新文件还是要 git add
  • git commit --amend [-m] [new-message] 修改提交记录
  • git commit -v 显示要添加到本地仓库所有diff信息
  • 将未提交的更改从当前分支移动到其他分支
    git stash
    git checkout branch2
    git stash pop
    
撤销&回滚
  • git checkout . 恢复所有暂存区文件到工作区(用来撤销工作区所有改动)
  • git checkout <file-name> 恢复暂存区文件到工作区(用来撤销工作区文件改动)
  • git checkout <commit-id> <file-name> 恢复某个commit的文件到暂存区和工作区
  • git reset [--mixed | soft | hard | merge | keep ]
    --mixed (默认模式) 仅重设暂存区,并把 HEAD 指向commit,但是不重设工作区,本地文件修改不受影响。(回退到某个版本,只保留源码,回退commit和index信息)
    --soft 工作区中的内容不作任何改变,HEAD 指向 commit自从 commit 以来的所有改变都会回退到“暂存区”中。(回退到某个版本,只回退了commit的信息。如果还要提交,直接 commit 即可。)
    --hard 重设暂存区和工作区 ,从commit以来在工作区中的任何改变都被丢弃,并把 HEAD指向commit。(彻底回退到某个版本,本地的源码也会变为上一个版本的内容。)
    --keep 保留工作区和HEAD之间差异部分,如果回退的内容与保留的修改存在冲突(有相同文件)则命令会失败。(不常用)
    --merge 保留暂存区和工作区之间的差异,如果回退的内容与保留的修改存在冲突(有相同文件)则命令会失败。(不常用)
    
  • git reset 重置HEAD,暂存区与上一次commit保持一致;但工作区不变
  • git reset --soft 重置HEAD与上一次commit保持一致;暂存区和工作区不变
  • git reset --hard 重置HEAD,暂存区,工作区与上一次commit保持一致
  • git reset <file-name> 重置暂存区的指定文件;但工作区不变
  • git update-ref -d HEAD 也就是把所有的改动都重新放回工作区,并清空所有的 commit,这样就可以重新提交第一个 commit 了
  • git diff --name-only --diff-filter=U 展示工作区的冲突文件列表
  • git reset <commit-id> 重置当前分支的指针为指定commit,同时重置暂存区,但工作区不变,指定commit之后的commit将抹除
  • git reset --soft <commit-id> 重置当前分支的HEAD为指定commit与指定commit一致,暂存区和工作区不变,指定commit之后的commit将抹除
  • git reset --hard <commit-id> 重置当前分支的HEAD为指定commit,同时重置暂存区和工作区,与指定commit一致,指定commit之后的commit将抹除
  • git revert -n <commit-id> 新建一个commit,用来撤销指定commit, 保留该目标commit后面的commit
  • git clean [-f|d|x] -n 显示将要被删除的文件
  • git clean 删除工作区未跟踪文件
  • git clean -d 删除工作区未跟踪文件夹
  • git clean -f [path] 强制删除
  • git clean -X -f 删除被.gitignore设置忽略的文件
  • 恢复到最近一次commit
    git reset --hard
    git clean -df
    
  • 抛弃本地所有的修改,回到远程仓库的状态
    git fetch --all && git reset --hard origin/master
    
  • 回滚远程代码
    git log #查看分支提交历史,确认需要回退的commit
    git reset --hard 551c2aa #进行commit回退
    git push -f origin master #推送至远程分支
    
  • 删除已经合并到 master 的分支
    git branch --merged master | grep -v '^\*\|  master' | xargs -n 1 git branch -d
    
合并&冲突
  • git merge [branch-name] 合并一个分支到当前分支,会把被合并分支和你当前分支的commit合并在一起,形成一个新的 commit 提交
  • git rebase [branch-name] 合并一个分支到当前分支,把你当前分支的commit放到被合并分支的最后面
  • git rebase -i HEAD~[num] 将最近num个commit合并成一个(这样推送到远程仓库后只有一个commit,避免污染远端的commit)
  • git pull --rebase 相当于 git fetch + git rebase
  • git checkout <branch-name> [--] <file-name> 从不同分支拉取当个文件
  • git checkout --theirs [file-name] 表示检出另外分支, 即保存另外分支的改动,丢弃当前分支的改动。冲突时直接使用他人的代码
  • git checkout --ours [file-name] 检出当前分支,即保存当前分支的改动,丢弃另外分支的改动。冲突时直接使用自己的代码
  • git cherry-pick <commit-id1> <commit-id2> ... 将指定的一些commit合并到当前分支
  • git cherry-pick <branch-name> 将所选分支的最近一次提交,转移到当前分支
  • 一次合并操作
    git checkout dev
    git rebase master
    #or git merge master
    #or git cherry-pick 8797a4f
    #出现冲突,修改文件后执行
    git add .
    #继续修改合并
    git rebase --continue
    #or git merge  --continue
    #or git cherry-pick  --continue
    #如果不想合并,直接终止
    git rebase --abort
    #or git merge --abort
    #or git cherry-pick  --abort
    
  • git merge与git rebase 使用建议
    公共分支使用merge,个人分支使用rebase
    本地和远端对应同一条分支,优先使用rebase,而不是merge
    
同步
  • git fetch <remote-host-name> <remote-branch-name> 更新远程代码到本地仓库,不会自动合并,后续可以对比本地分支与线上分支的差别
  • git merge <remote-host-name>/<remote-branch-name> 把远程下载下来的代码合并到本地仓库
  • git pull <remote-host-name> <remote-branch-name>:<local-branch-name> 拉取远程分支更新到本地仓库,并自动merge
    #git pull = git fetch + git merge
    #不推荐直接用git pull,推荐用下面命令
    git fetch origin master
    #对比改动,然后合并
    git diff HEAD FETCH_HEAD
    git merge origin/master
    
  • git pull <remote-host-name> --tags 拉取远程标签
  • git remote -v 显示所有远程仓库
  • git remote show <remote-host-name> <remote-branch-name> 显示某个远程仓库的信息
  • git remote add <remote-host-name> <git-url> 增加一个新的远程仓库,并命名
  • git push <remote-host-name> <remote-branch-name> 将本地分支推送到与之存在追踪关系的远程分支(通常两者同名),如果该远程分支不存在,则会被新建
  • git push <remote-host-name> :refs/for/<remote-branch-name> 删除指定的远程分支1
  • git push <remote-host-name> --delete <remote-branch-name> 删除指定的远程分支2
  • git push <remote-host-name> 如果当前分支与远程分支存在追踪关系,则本地分支和远程分支都可以省略,将当前分支推送到origin主机的对应分支
  • git push 如果当前分支只有一个远程分支,那么主机名都可以省略
  • git push -u <remote-host-name> <remote-branch-name> 如果当前分支与多个主机存在追踪关系,则可以使用 -u 参数指定一个默认主机,这样后面就可以不加任何参数使用git push
  • git push --all <remote-host-name> 不管是否存在对应的远程分支,将本地的所有分支都推送到远程主机
  • git push --force <remote-host-name> 强制推送到远程主机
  • git push <remote-host-name> --tags 推送标签
subtree
  • git subtree add --prefix=<sub-repository-path> <sub-git-url> master [--squash] 在父仓库中新增子仓库
  • git subtree pull --prefix=<sub-repository-path> <sub-git-url> master [--squash] 拉取更新子仓库
  • git subtree push --prefix=<sub-repository-path> <sub-git-url> master 推送子仓库
  • 给子仓库添加远程仓库,方便复用子仓库git仓库地址
    git remote add -f <sub-remote-git> <sub-git-url>
    git subtree add --prefix=<sub-repository-path> <sub-remote-git> master
    
子模块(submodule)
  • git submodule add <sub-git-url> <sub-repository-path> 添加子模块
  • git submodule foreach git pull [remote-host-name] [remote-branch-name] 更新
  • git clone <git-url> --recursive clone 主库和子模块
  • git submodule init 初始化本地配置文件
  • git submodule update 检出父仓库列出的commit
  • 更新整个仓库
    git pull
    git submodule init && git submodule update // or git submodule update --init --recursive 
    git submodule foreach git pull origin master // 更新代码时使用
    
  • 删除子仓库(sub-repo)
    git rm --cached sub-repo
    rm -rf sub-repo
    删除 .gitmodules 文件 [submodule "sub-repo"] 相关内容
    删除 .git/config 文件 [submodule "sub-repo"] 相关内容
    
大文件管理(lfs)
  • git lfs track "<pattern-file-name>" 跟踪需要处理哪些文件
    #追踪所有后缀为a的文件
    git lfs track "*.a"  
    
  • git lfs ls-files 可以显示当前被lfs追踪的文件列表
  • git lfs track 查看现有的文件追踪模式
  • git lfs untrack "*xx.a" 取消git fls对xx.a的追踪管理
  • git lfs version 查看当前所用git lfs版本
  • git lfs pull 从远程仓库拉取大文件
  • 安装
    #详细见
    https://github.com/git-lfs/git-lfs#downloading
    
其他
  • 安装
    #详情见官网下载页
    https://git-scm.com/downloads
    
  • git archive --format=zip <branch-name> > <file_name> 打包
    git  archive --format=zip master > nb.zip
    
  • -- 转义符
    git checkout -- master
    #前面加上‘--’代表master是一个文件,不是master分支
    
  • git help <command> 查看帮助
    git help -a
    git help add
    
  • github 加速
    https://fhefh2015.github.io/Fast-GitHub/
    https://ghproxy.com/
    #other 
    vi ~/.gitconfig
    [url "https://ghproxy.com/https://github.com/"]
    insteadOf = https://github.com/