Git Commands

Git常用命令

Posted by Hao on February 19, 2021

Git常用命令

Git基础命令

git clone

  • git clone [url]:拉取远程仓库
  • git clone --depth 1 [url]:拉取远程仓库,且只拉取最近的一次commit,限制 clone 的深度,不会下载 Git 协作的历史记录,这样可以大大加快克隆的速度。但后期无法访问其他的远程分支了。对应的解决方案见Q&A。

git fetch

.git/FETCH_HEAD

  • git fetch --all
  • git fetch origin(remote_repo_name) <remote_branch_name>:<local_branch_name>拉取库的远程非master分支到本地分支
  • git fetch origin(remote_repo_name) <remote_branch_name>拉取库的远程分支到本地分支,本地分支名可省略,默认和远程分支一样
  • git fetch --depth 1 origin(remote_repo_name) <remote_branch_name>拉取库的远程分支到本地分支,本地分支名可省略,默认和远程分支一样,且只拉取最近的一次commit

git fetch更新代码后,本地分支(即Head指针指向的分支)不会改变,commit维持原始提交,但本地remotes文件下对应的远程跟踪分支会同步更新远程仓库最新提交。

git diff

  • git diff直接使用,可以查看当前的本地改动与前一次commit之前的区别。无参数的git diff比较的是工作区,即未add到暂存区的内容。不同于git st的是,其能显示具体每个文件的代码行的修改。
  • git diff --cached 将暂存区的内容,即通过git add添加后的内容与最近一次commit进行比较。
  • git diff commit_id 工作区与指定的commit进行比较
  • git diff --cached commit_id 暂存区与指定的commit进行比较
  • git diff <branch1> <branch2> 列出两个分支下的所有文件区别
  • git diff <branch1> <branch2> <__PATH_NAME__> 列出两个分支下的具体某个文件的区别
  • git diff <branch1> <branch2> --stat 列出两个分支下的差异文件的列表

git log

  • git log -n <number> 用于查询git commit的结果,并输出最近的次提交
  • git log -n <number> --oneline 用于查询git commit的结果,并输出最近的次提交,并只输出一行结果

git push

  • git push直接使用,是默认将本地的该branch推到远程端的同名branch或相关的branch上
  • git push -u origin <local_branch_name>:<remote_branch_name> 需要为新的本地branch推到远程端时使用,建立两个branch之间的连接

git merge

  • git merge --ffgit merge --fast-forward(default):无参数时的默认合并方式,在进行合并时,不会创建一个新的结点,会将当前分支与master分支直接合并,并将HEAD指针指向合并后的结点
  • git merge --no-ff -m "description" <branch_name>:禁用fast-forward模式,在合并时会创建一个新的commit,显示分支合并的过程,可以通过加入description讲述合并细节,如果通过gitlab的界面合并,或者不加description合并,一般默认的消息为:merge branch "A" into branch "B"
  • git merge --squash -m "description" <branch_name>:清除该分支中不想合并的commit记录,将目标分支与当前分支合并,且清除目标分支的commit节点,通过description添加本次分支合并的细节

  • git merge --abort:在合并后导致冲突时使用,用来恢复合并前的状态

git pull

git pull = git fetch + git merge

git pull将远程仓库里最新的代码版本直接替换到本地Head指针下的本地仓库分支。一般默认为master/main分支

git branch

  • 刪除本地分支
    1
    2
    
     $ git branch -d <branch_name>
     $ git branch -D <branch_name>  //強制刪除本地分支
    
  • 刪除远程分支
    1
    
     $ git push origin --delete <remote_branch_name>
    
  • 删除远程分支与本地分支的联系
    1
    
    $ git branch --remote --delete <origin/remote_branchname>
    
  • git branch:查看本地分支
  • git branch -r:查看远程分支
  • git branch -a:查看本地及远程分支/所有分支
  • git branch <branch_name>:创建新分支
  • git branch (-m | -M | --move) <old_branch_name> <new_branch_name>
  • git branch -v: verbose 模式,给出每个branch的最后一次commit的hash和msg
  • git branch -vv: extra verbose 模式,给出每个branch的最后一次commit的hash和msg,以及每个branch对应的upstream

git add

  • git add -u : 只将所有已经tracked的文件的修改加入缓存,并不会加入新的文件
  • git add -A : 将与上次提交不同的所有文件加入缓存
  • git add -f <file>: 强制添加某文件,忽略gitignore

git rm

  • git rm --cache <file>: 不删除物理文件,仅将该文件从缓存中删除;
  • git rm -f <file>: 删除缓存并删除物理文件

git clean

  • git clean -d: 清空所有新建的文件和文件夹
  • git clean -nxdf: 先看下即将删除那些文件,再执行下面的危险命令
  • git clean -df: 删除所有未跟踪的文件和目录(不包含.gitignore的文件)
  • git clean -xdf: 删除所有未跟踪的文件和目录(同时包含.gitignore的文件)

git restore

  • git restore <file>:对工作目录中已改变的文件进行复原,不会对新添加的(untracked的)文件产生影响

git commit

  • git commit -a:对于tracked文件,可以直接保存到暂存区并提交。即在未新建或删除文件的前提下,可以直接通过此命令省去通过git add将内容存到暂存区的过程
  • git commit -m "<description>": 对本次提交内容加入注释,如需多行及标题,则不设置后引号,输入前引号及标题内容后,回车进入下一行,在最终文本处加入后引号,回车以结束输入
  • git commit --amend -m "<description>": 修改最近一次的提交内容,也可以使用--amend后进入交互模式,但根据默认编辑器的不同,交互模式下的编辑,保存方法也有所不同。具体查看是否成功通过amend命令对原始内容进行修改,可以通过git reflog进行查看。注意:通过--amend修改后的commit与原版本的commit_id不同
  • git commit --amend --no-edit: 将本次的修改内容与上次修改内容合并提交,并使用上次的commit description

git checkout

  • git checkout -- <File_name>:放弃某个文件在工作区的修改
  • git checkout .:放弃当前目录下工作区的所有修改,暂存区(已经通过git add添加的)不影响
  • git checkout <branch_name>:切换当前分支
  • git checkout -b <branch_name>:切换当前分支
  • git checkout --orphan <branch_name>:新建一个分支且不记录原分支所有的原始commit
  • git checkout -b <local_branch_name> origin/<remote_branch_name>:新建一个分支并跟踪库的远程分支

git reset

git reset常用于版本回滚,可以直接删除近期的commit记录

  • git reset <commit_id/HEAD>
    • git reset --soft:只改变当前HEAD指针的指向版本,即原版本的已经提交到本地仓库的内容会重新加载回暂存区/索引中,此时使用git commit可以重新修改description等内容,或者回退多个版本,最终只提交一次commit,即合并commit,相同功能命令可参考git commit --amend
    • git reset --mixed (default):默认选择,可用于取消之前通过git add添加到暂存区/索引的内容,但不会修改本地仓库的修改。即已使用git add命令但未使用git commit命令
    • git reset --hard: 完全丢失本地改动,可用于回退本地版本或回退远程版本(通过强制推送到远程仓库实现)

git revert

git revert会创建一个新的commit来实现版本的回滚

  • git reset <commit_id/HEAD>
  • git reset -n <commit_id/HEAD>或git reset –no-commit <commit_id/HEAD>
  • git reset -m <merge_commit_id/HEAD> 撤销merge节点的提交

如何回退到相应的版本?

  • 通过指定具体的commit_id
  • 最近一次的提交HEADHEAD~0
  • 距离最新commit位置2次前的提交HEAD^^HEAD~2

Git进阶命令

git stash

  • git stash: 存储当前改动
  • git stash list: 显示保存进度的列表。
  • git stash drop [stash@{id}]: 删除存储的某个进度,默认参数为最近的存储进度
  • git stash clear: 删除存储的所有进度
  • git stash apply/pop: apply恢复最新的进度到工作区,但并不删除stash拷贝;pop会删除拷贝。git默认会把工作区和暂存区的改动都恢复到工作区
  • git stash pop --index: 恢复最新的进度到工作区和暂存区。(尝试将原来暂存区的改动还恢复到暂存区)
  • git stash save --keep-index: 将工作区的内容(未使用git add)进行存储,此时可只测试暂存区的内容(已经通过git add命令添加的部分)
  • git stash pop [stash@{id}]: 恢复指定的进度到工作区。stash_id是通过git stash list命令得到的通过git stash pop命令恢复进度后,会删除当前进度。
    1
    2
    3
    4
    
     $ git stash list
     stash@{0}: master: 049d078 added the index file
     stash@{1}: master: c264051 Revert "added file_size"
     stash@{2}: master: 21d80a5 added number to log
    
  • git stash store -m "message": 用于存储本地修改并基于注释,修改只发生在本地
  • git stash show: 可以用来查看存储内容与当前工作区的差异,通过指定stash_id查看某次存储与当前目录差异,通过-p查看具体代码
  • git stash show -p [stash@{id}] | git apply -R: 用于取消已经应用后的修改

git rebase

不同分支之间进行rebase

  • git rebase <branch_name>: 在当前分支和branch_name共有的代码基础上,把branch_name(基于共有代码)新增的修改应用到当前分支上。(基于两个branch的共有代码,讲每次新的commit都以batch的形式加进来,解决每次冲突)
  • git rebase --continue: 继续解决下一个冲突,重复这这些步骤,直到rebase完成
  • git rebase --skip: 使用此命令忽略不需要修改的补丁,即用rebase前的原始分支取代当前分支的所有文件
  • git rebase --abort: 放弃之前进行的rebase操作

单个分支进行rebase,用于修改历史commit

  • git rebase -i HEAD~5: 最后一个数字是你要查看的最近向后提交的任意数量,之后在vim中,按esc,然后按i开始编辑测试。根据所需对commit进行修改和调整,此步骤只能使用其他命令修改左侧pick命令,例如editfixupreword等,保存并推出文本编辑器。如果有需要修改commit,下一步会进入新的文本编辑器,修改需要的commit,此时同git commit --amend命令的效果一样。针对Vim的简易指令:如果你没有做任何改变,输入 :q ,然后按Enter/return. 如果你做了一些改变,并希望保留它们,输入 :wq 并按Enter/return. 如果你做了一些修改,并希望放弃它们,请输入 :q! 并按Enter/return
  • git rebase --continue: 继续解决下一个冲突,重复这这些步骤,直到rebase完成
  • git rebase --skip: 使用此命令忽略不需要修改的补丁,即用rebase前的原始分支取代当前分支的所有文件
  • git rebase --abort: 放弃之前进行的rebase操作

git reflog

git reflog可以查看所有分支的所有操作记录,即每次改变Head的操作。(包括commitreset的操作),包括已经被删除的commit记录。当某个本地分支没有远程备份,且在本地被删除的情况下,可以通过调用当时该分支的commitID来复原。

  • git reflog -<n>: 可以查看最近n次的操作记录

git tag

常用于版本发布,或者特殊版本的记录

1
2
$ git tag  //查看当先库的已有tag
$ git fetch --tags //拉取远程库的已有tag

patch

origin

如果已经配置远程仓库服务器,可以通过运行git remote命令查看已经克隆的远程仓库,而origin为默认的远程仓库名,可以看做为地址git@github.com/repo.git的别名

Case 1 新建仓库且添加别名为private的远程仓库:

1
2
3
4
5
$ git init  //初始化
$ git add README.md
$ git commit -m "first commit"
$ git remote add private git@github.com/repo.git    //添加远程仓库并起别名为private
$ git push -u private master //-u等价于--set-upstream,将本地仓库推到private仓库的master分支

git remote

git remote命令常用于为本地仓库创建远程仓库。例如已有原始开源仓库origin,但需要推送到自己的仓库private,可实现一个本地仓库对接两个远程仓库

其中,原始的开源仓库地址为git@github.com/repo.git,打算推到的私人仓库的地址为git@github.com/private_repo.git

1
2
3
   $ git remote add private git@github.com/private_repo.git    //链接到远程私人仓库并起别名为private
   $ git push -u private master //-u等价于--set-upstream,将本地仓库推到private仓库的master分支
   $ git remote rm origin  //删除git的某个远程仓库
  • git remote [-v | --verbose]:输出远程链接库的详细信息
  • git remote set-url origin [url]:直接修改远程仓库地址,例如git remote set-url origin https://ddns.togit.cc:7777/rffanlab/tensorflow_get_started_doc_cn.git

git remote show origin:获取远端分支的信息,查看远端分支与本地分支的track情况以及同步情况。部分远程分支在删除本地分支,删除远程分支后,未在本地删除对远程分支的同步track指针,此时会显示本地对改远程分支的状态是stale,即已经不再更新了,此时,需要通过git remote prune origin命令来清除此类分支或让下拉到本地的远程分支状态与远程分支状态同步。

git bundle

  • git bundle create <filename> <branch_name>: 对某个库的制定分支进行打包,并打包到某个文件中
  • git bundle create <filename> -all: 对某个库的所有分支进行打包,并打包到某个文件中
    • git clone <filename>: 通过git clone命令对该文件创建本地库 当使用master分支进行打包时,需要通过git checkout master命令将指针指向master分支后,才能显示文件中所含内容,否则为空文件

git cherry

可以通过使用git cherry -v查看已经提交,但未传送到远程代码库的提交描述/说明

git cherry-pick

针对当前分支只需要某个分支的具体某次或者几次commit,可以使用cherry-pick来把需要的commit移植到当前分支。基于commitHash是unique的原理。

在需要拉取的分支查看当前的<commitID>or<commitHash>,之后切换到需要更新的分支,使用

  • git cherry-pick <HashA> <HashB>

如果想要转移一系列的连续提交,可以使用下面的简便语法。

  • $ git cherry-pick A..B

上面的命令可以转移从 A 到 B 的所有提交。它们必须按照正确的顺序放置:提交 A 必须早于提交 B,否则命令将失败,但不会报错。注意,使用上面的命令,提交 A 将不会包含在 Cherry pick 中。如果要包含提交 A,可以使用下面的语法。

  • $ git cherry-pick A^..B

Cherry pick 也支持转移另一个代码库的提交,方法是先将该库加为远程仓库。

将远程代码仓库抓取到本地。接着,检查一下要从远程仓库转移的提交,获取它的哈希值。最后,使用git cherry-pick命令转移提交。