记录下git常用命令,方便查阅。
1.查看版本号
git --version
2.配置
安装完 Git 之后,要做的第一件事就是设置你的用户名和邮件地址。这一点很重要,因为每一个 Git 提交都会使用这些信息,它们会写入到你的每一次提交中,不可更改:
1.查看配置
--local:当前仓库配置 --global:全局配置 --system:系统配置 生效顺序:system 包含工作区,在目录下有.git目录。 裸仓库:不包含工作区。类似于普通仓库的.git目录里的内容。一般用于远程仓库,远程仓库不能直接操作工作区(因为没有工作区),必须clone到本地进行修改,然后再推送到远端。 git diff:比较工作区与暂存区差异。注意:只能比较已被git管理的文件的变动。如果是新增文件,则无法比较。(还没执行git add) git diff --staged/--cached:比较已暂存文件与最后一次提交的文件差异。(执行了git add但没有执行git commit) --amend命令会将暂存区中的文件提交。 如果自上次提交以来你还未做任何修改(例如,在上次提交后马上执行了此命令), 那么快照会保持不变,而你所修改的只是提交信息。 提交后发现忘记了暂存某些需要的修改,可以像下面这样操作,最终只会有一个提交:第二次提交将代替第一次提交的结果。 默认clone的仓库会有个远程仓库:origin(别名)。 git remote add <远程简写> <远程地址> git pull的默认行为是git fetch + git merge git pull --rebase则是git fetch + git rebase 如合并发生冲突,需要解决冲突,然后执行 dev分支是基于master分支新建的。如想把dev的修改变基到master,需要执行以下操作: 或者使用简化代码: --hard:不保存修改。--soft:保存修改。 revert能在不修改commit历史下,让代码回滚到某次提交。 例如有A、B、C三个提交。现在想把代码修改回到B,但是保留之前的commit,可以用revert。 A(hash:01457d561cd177)B(hash:7ece6165996e0d)C(hash:85cb8fc446f585) X..Y :等价于 (X, Y] 左开右闭区间。也就是从X开始到Y结束,不包括X。 X...Y:不同时在X与Y中的。也就是X与Y的交集以外的部分。 git blame 能显示任何文件中每行最后一次修改的提交记录。 结果如下: 注意一下 场景:A、B两个仓库,现需要把B仓库的代码合并到A仓库。 2.将仓库B代码下载到本地 3.在本地创建B的分支 4.切换到A仓库分支 5.合并B分支 6.覆盖合并 仓库迁移不仅会将所有代码迁移到新仓库,而且会保留所有的commit和tag。// 查看所有的配置
git config --list
// 查看所有的配置以及它们所在的文件
git config --list --show-origin
// 查看全局仓库配置
git config --list --global
// 查看当前仓库用户名(可不带--local)
git config --local user.name
// 查看全局仓库用户名
git config --global user.name
2.配置信息
// 配置当前仓库用户名(与--local等价)
git config user.name "testleo"
// 配置当前仓库用户名
git config --local user.name "testleo"
// 配置全局仓库用户名
git config --global user.name "testleo"
// 配置全局仓库邮箱
git config --global user.email "[email protected]"
// 配置默认分支为main(不配置为master)
git config --global init.defaultBranch main
3.帮助
// 查询add命令的使用
git help add
// 查询add命令的使用
git add --help
// 查询add命令的使用
man git-add
// 查询add命令的简明使用
git add -h
4.init
1.创建仓库
// 在my_project目录下初始化git(my_project/.git)(如my_project目录不存在,则创建)
git init my_project
// 等价于
mkdir my_project; cd my_project; git init
2.创建裸仓库
// 直接初始化
git init --bare my_project.git
// 从已有的普通仓库生成
git clone --bare my_project my_project.git
// 整体上效果大致相当于
cp -Rf my_project/.git my_project.git
5.clone
//
// 从保存在本地的远端仓库clone
git clone ./my_project local_project
// 从远端clone,默认命名libgit2
git clone https://github.com/libgit2/libgit2
// 从远端clone,命名mylib2
git clone https://github.com/libgit2/libgit2 mylib2
6.status
// 使用检查当前文件状态
git status
7.diff
// 比较工作区与暂存区差异
git diff
// 比较已暂存文件与最后一次提交的文件差异
git diff --staged
// 比较上一次提交与当前提交的区别(如当前提交有新增,则会以+形式体现)
git diff HEAD^ HEAD
// 比较master分支与dev分支区别
git diff master dev
// 比较两次提交的区别
git diff 3fc77104 557b6608
8.add
// 把所有变更的文件放到暂存区。新增文件:加入git管理并放入暂存区。git已管理变更:把变更放入暂存区。
git add .
// 把README、README2加入git管理并放入暂存区 新增README文件路径为:v1/v2/README2
git add README v1
9.restore
// 把所有放到暂存区的文件从暂存区移除
git restore --staged .
// 把加入git管理并放入暂存区的README、README2从暂存区移除 README文件路径为:v1/v2/README2
git restore --staged README v1
// 把工作区的修改重置 同:git checkout -- README
git restore README
10.rm
// 把加入暂存区的v1目录及子目录及文件从暂存区移除并删除目录
git rm -rf v1
// 把加入暂存区的README从暂存区移除,同 git restore --staged README
git rm --cached README
// 把加入暂存区的README从暂存区移除并删除
git rm -f README
11.commit
// 把添加到暂存区的文件进行提交
git commit -m "init"
// 跳过暂存区把未暂存的文件提交(只会提交已被git管理的文件)(新增的文件不会提交)
git commit -a -m "init"
// 跳过暂存区把未暂存的文件提交(只会提交已被git管理的文件)(新增的文件不会提交)
git commit -am "init"
// 重新提交
git commit --amend
git commit -m 'initial commit'
git add forgotten_file
git commit --amend
12.mv
// 把README重命名为readme.md
git mv README readme.md
// 等价于下面三条命令
mv README readme.md
git rm README
git add readme.md
13.branch
// 查看本地分支
git branch
// 查看本地分支及对应的提交
git branch -v
// 查看本地分支与跟踪的远程分支
git branch -vv
// 查看本地分支与跟踪的远程分支及远程分支
git branch -avv
// 查看远程所有分支
git branch -r
// 查看本地和远程所有分支
git branch -a
// 查看哪些分支已经合并到当前分支
git branch --merged
// 查看所有包含未合并工作的分支
git branch --no-merged
// 创建dev分支
git branch dev
// 删除本地dev分支,如无法删除(该分支未合并),使用 -D
git branch -d dev
// 删除本地暂存的远端dev分支,如无法删除,使用 -D
git branch -d -r origin/dev
// 删除远端dev分支 方式1
git push origin -d dev
git push origin --delete dev
// 删除远端dev分支 方式2
git push origin :dev
// 让本地master分支跟踪远端main分支。(如当前在master分支,可省略最后的master参数)
// 可以为一个本地分支设置多个跟踪。设置跟踪前应先调用:git pull origin main 把远程的索引更新到本地。
git branch -u origin/main master
// 取消本地分支与远端分支的跟踪,先取消跟踪才能设置跟踪
git branch --unset-upstream
// 把本地master分支重命名为main
git branch -m master main
// 创建并切换bugfix分支
git checkout -b bugfix
// 设置bugfix分支跟踪远程dev分支
git branch -u origin/dev
// 查找包含当前提交的本地分支
git branch --contains 0f0e9c938721
// 查找包含当前提交的本地分支与远程分支
git branch -a --contains 0f0e9c938721
14.remote
// 查看远程仓库别名
git remote
// 查看远程仓库别名及对应URL
git remote -v
// 添加远程仓库../next_remot,命名为pb
git remote add pb ../next_remot
// 添加远程仓库并命名为pb
git remote add pb https://github.com/paulboone/ticgit
// 查看远程仓库origin详细信息(可看到远程分支情况及远程分支与本地分支跟踪情况。)
git remote show origin
// 查看远程仓库pb更多信息
git remote show pb
// 把远程仓库pb重命名为paul
git remote rename pb paul
// 把远程仓库paul移除
git remote remove paul
15.pull
// 拉取远端origin的master分支(fetch),并把本地master与远端master代码合并(merge)。
git pull origin master
// 假设当前分支为master,且与远端分支建立了关联。拉取远端origin的master分支(fetch),并把本地master与远端master代码合并(merge)。同 git pull origin master
git pull
// 允许本地与远程没有共同父节点的合并拉取操作(常见于仓库初始化,但本地远端都有仓库时)
git pull --allow-unrelated-histories origin master
16.push
// 推送tag到远程仓库
git push origin v1.5
// 所有不在远程仓库服务器上的标签全部传送到那里
git push origin --tags
// 删除远程仓库中的tag
git push origin --delete v1.5
// 推送本地master分支到远端
git push origin master
// 推送当前分支到远端
git push
17.fetch
// 获取当前分支跟踪的远程分支的更新
git fetch
// 获取远程分支dev的更新
git fetch origin dev
// 获取所有远端更新(不合并)
git fetch --all
18.merge
// 切换到master分支
git checkout master
// 把dev分支合并到master分支
git merge dev
git add .
git commit -m "解决冲突"
19.rebase
// 1.切换到dev分支
git checkout dev
// 2.以master作为基底,把dev分支的修改变基到master(此时dev上已有master的修改,且在共同父节点后,master的修改在前,dev的修改在后。)
git rebase master
// 3.切换到master分支
git checkout master
// 4.把dev的代码以快进的方式合并到master分支
git merge dev
// 1.以master作为基底,把dev分支的修改变基到master(此时dev上已有master的修改,且在共同父节点后,master的修改在前,dev的修改在后。)
git rebase master dev
// 2.把dev的代码以快进的方式合并到master分支
git merge dev
// 变基发生冲突后,修改冲突并执行以下代码
git add .
// 继续变基
git rebase --continue
// 取消变基
git rebase --abort
20.log
// 树状形式、每个提交一行 显示历史记录
git log --graph --pretty=oneline
// 查看当前分支提交记录
git log
// 最近的两次提交及所引入的差异
git log -p -2
// 每个提交放在一行显示
git log --pretty=oneline
// 以特定格式显示
git log --pretty=format:"%h - %an, %ar : %s"
// 树状形式显示提交历史
git log --graph
git log --pretty=format:"%h %s" --graph
// 仅显示添加或删除内容匹配指定字符串function_name的提交。
git log -S function_name
常用选项:
%H:提交的完整哈希值
%h:提交的简写哈希值
%T:树的完整哈希值
%t:树的简写哈希值
%P:父提交的完整哈希值
%p:父提交的简写哈希值
%an:作者名字
%ae:作者的电子邮件地址
%ad:作者修订日期(可以用 --date=选项 来定制格式)
%ar:作者修订日期,按多久以前的方式显示
%cn:提交者的名字
%ce:提交者的电子邮件地址
%cd:提交日期
%cr:提交日期(距今多长时间)
%s:提交说明
-p:按补丁格式显示每个提交引入的差异。
--stat:显示每次提交的文件修改统计信息。
--shortstat:只显示 --stat 中最后的行数修改添加移除统计。
--name-only:仅在提交信息后显示已修改的文件清单。
--name-status:显示新增、修改、删除的文件清单。
--abbrev-commit:仅显示 SHA-1 校验和所有 40 个字符中的前几个字符。
--relative-date:使用较短的相对时间而不是完整格式显示日期(比如“2 weeks ago”)。
--graph:在日志旁以 ASCII 图形显示分支与合并历史。
--pretty:使用其他格式显示历史提交信息。可用的选项包括 oneline、short、full、fuller 和 format(用来定义自己的格式)。
--oneline:--pretty=oneline --abbrev-commit 合用的简写。
21.reset
// 把暂存区中的README从暂存区中移除 同:git restore --staged README
git reset HEAD README
// 会重置所有在工作区、暂存区中的内容(可以省略HEAD)到最后一次提交,不保留修改
git reset --hard
git reset --hard HEAD
// 重置代码到上一个提交(HEAD代表当前提交,HEAD^代表上一次提交)
git reset --hard HEAD^
// 重置代码到指定提交
git reset --hard 0f0e9c938721
// 重置代码到最后一次提交,并保留修改
git reset --soft
22.checkout
// 切换到dev分支
git checkout dev
// 创建dev分支并切换到该分支(省略了HEAD,基于当前HEAD)
git checkout -b dev
// 创建dev分支并切换到该分支(基于d74bfcf的提交)
git checkout -b dev d74bfcf
git checkout -b dev
// 是以下命令的简写
git branch dev
git checkout dev
// 把工作区的修改重置 同:git restore README
git checkout -- README
// 检出到tag:v1.5,此时处于分离头指针(detached HEAD)
git checkout v1.5
// 基于tag:v1.5创建分支tagBranch1_5并切换到该分支
git checkout -b tagBranch1_5 v1.5
// 基于当前分支创建本地分支(如远端有origin/dev分支,需要手动创建关联)
git checkout -b dev
// 基于远程dev分支创建本地分支(自动创建本地与远端的关联)
git checkout -b dev origin/dev
// 如远端有origin/dev分支,自动创建关联并切换到dev分支
git checkout dev
// 创建本地serverfix分支并切换到serverfix分支,且跟踪远端serverfix分支
git checkout --track origin/serverfix
23.tag
// 列出标签
git tag
// 列出匹配v1.8.5*的tag
git tag -l "v1.8.5*"
// 标签信息和与之对应的提交信息
git show v1.4
// 打v1.4的tag并为tag添加描述
git tag -a v1.4 -m "the tag version:1.4"
// 在9fceb02提交打tag
git tag -a v1.2 9fceb02
// 删除本地tag
git tag -d v1.2
git push origin v1.5
// 检出到tag:v1.5,此时处于分离头指针(detached HEAD)
git checkout v1.5
// 基于tag:v1.5创建分支tagBranch1_5并切换到该分支
git checkout -b tagBranch1_5 v1.5
24.stash
// 已被跟踪但未被commit的修改暂存(未被跟踪的需要执行git add才能被暂存)
git stash
// 暂存修改并命名
git stash save "第一次暂存"
// 查看暂存列表
git stash list
// 把最后一次暂存应用到当前工作区
git stash apply
// 把第二次暂存(下标从0开始)应用到当前工作区
git stash apply stash@{1}
// 把最后一次暂存应用到当前工作区,并删除暂存
git stash pop
// 把第二次暂存(下标从0开始)应用到当前工作区,并删除暂存
git stash pop stash@{1}
// 删除单个缓存
git stash drop stash@{0}
// 清除所有暂存
git stash clear
// 显示与当前分支具体差异
git stash show stash@{0} -p
25.reflog
git log
是显示当前的HEAD和它的祖先的,递归是沿着当前指针的父亲,父亲的父亲,这样的原则。
git reflog
根本不遍历HEAD的祖先。它是HEAD所指向的一个顺序的提交列表:它的undo历史。
reflog并不是repo(仓库)的一部分,它单独存储,而且不包含在pushes,fetches或者clones里面,它纯属是本地的。
reflog可以很好地帮助你恢复你误操作的数据,例如你错误地reset了一个旧的提交,或者rebase,这个时候你可以使用reflog去查看在误操作之前的信息,并且使用 git reset --hard 去恢复之前的状态。git reflog show
26.revert
两个点
三个点
// HEAD:C HEAD^:B(倒数第二次提交)
git revert HEAD~2..HEAD
// 与上面等价
git revert 01457d561cd177..85cb8fc446f585
// 与上面等价(注意顺序,最后提交的在最前面)
git revert HEAD HEAD^
// 与上面等价
git revert 7ece6165996e0d 85cb8fc446f585
// 只把代码回退,不提交
git revert --no-commit HEAD^ HEAD
HEAD~1等价于HEAD^
HEAD~2等价于HEAD~1^
27.cherry-pick
28.blame
// 显示README每一行的最后一次提交记录
git blame ~/Desktop/test/README
// 显示README第69行到第82行的最后一次提交记录
git blame -L 69,82 ~/Desktop/test/README
b8b0618cf6fab (Cheng Renquan 2009-05-26 16:03:07 +0800 69) ifeq ("$(origin V)", "command line")
b8b0618cf6fab (Cheng Renquan 2009-05-26 16:03:07 +0800 70) KBUILD_VERBOSE = $(V)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 71) endif
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 72) ifndef KBUILD_VERBOSE
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 73) KBUILD_VERBOSE = 0
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 74) endif
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 75)
066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 76) ifeq ($(KBUILD_VERBOSE),1)
066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 77) quiet =
066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 78) Q =
066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 79) else
066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 80) quiet=quiet_
066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 81) Q = @
066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 82) endif
^1da177e4c3f4
这个提交的几行,其中的前缀 ^
指出了该文件自第一次提交后从未被修改过。29.grep
30.不同仓库代码合并
1.在A仓库下添加远端索引git remote add b_remote b仓库地址
git fetch b_remote
git checkout -b b_local b_remote/devOld
git checkout dev
--allow-unrelated-histories:允许没有关联的分支合并git merge b_local --allow-unrelated-histories
覆盖合并相当于删除了被覆盖分支的内容。
当前处于A仓库dev分支,以下命令是把B分支的devOld代码覆盖到了A仓库dev分支git reset -hard devOld
30.仓库迁移
随便cd到一个目录,然后执行:// 1、从原地址克隆一份裸仓库
git clone --bare xxx/oldproject
// 2、进入到裸仓库
cd oldproject.git
// 3、推送到新地址
git push --mirror xxx/newproject