版本管理工具 Git 的使用
就软件开发来说, 不管是个人开发还是团队协作, 版本管理工具肯定必不可少. 其中分布式版本管理工具 git 由于其优良的性能, 可靠的安全性最为被接受, 也是最为普及的.
在完整地看了几个教程并且实战了一段时间后, 我将日常使用的命令以及个人理解总结成本文. 本文涉及内容有初级, 有高级, 如果能完全掌握这些命令绝对能在工作中祝你一臂之力. 建议收藏以备以后检索相关命令. 😁
分布式存储与集中式存储的区别
- 都有一个中央仓库
- 团队合作开发中每个人的仓库最终都必须同步到中央仓库
- 中央式存储没有个人仓库的概念, 因此只有做完一个小功能后上传到中央仓库才会有一个记录节点. 这样会导致一个提交里面包含很多代码, 不利于回溯.
- 分布式存储有个人仓库, 每个人做完一个极小的功能后可以先
commit
, 然后再 push, push 到中央仓库后也会将自己的诸多小commit
传上来.(如果不需要那么多小commit
的话可以使用rebase
依次合并多个小commit
然后再统一push
) - 分布式存储由于在每个机器上都会有完整的存储仓库, 因此本地占用会比较大, 初次 clone 也会稍微费事一些
- 结合以上特点, 由于软件开发主要是文本代码, 而这些资料的占用空间并不大, 而且软件开发对历史回溯要求比较高, 因此一般都是使用分布式存储. 集中式存储主要用于某些占用体积超大的项目开发领域, 比如大型游戏.
Git 特点概括
Git
的管理是目录级别, 而不是设备级别的, 即两个不同的目录存着同样地址的仓库的话会被认为是两个不同的仓库, 可以用于模拟为两个人.git
是以 line 为最小单位进行判断的, 即如果序号1
的行被 branch 修改了, 序号2
的行被master
修改了, 那么在merge branch
与master
的时候结果就是序号1
与2
都被修改了. 但是两个branch
都在序号1
的行修改了, 那么就会冲突, 会提示手动解决冲突. 一个仓库中的文件都会被 git 系统监视, 一共有以下 3 种状态未被跟踪
: 新建文件都不会被跟踪. 需要手动add
进入暂存区已保存
: 已经在系统中保存了此文件, 被放在保存区
未放入暂存区(changes not staged for commit)
已暂存
:commit(changes to be commited)
, 被放入暂存区
. 等待commit
中
- 其实
reset
的三个状态正好对应了文件的几种保存状态--hard
: 回退commit
, 将两个commit
之间的改动放入暂存区, 再将暂存区所有文件放到保存区, 再将保存区
文件删除. 最硬的--mixed
: 回退commit
, 将两个commit
之间的改动全部放入暂存区
, 再将暂存区所有文件放到保存区
--soft
: 回退commit
, 两个commit
之间的改动全部放入暂存区
. 最软的.
reset
的三种模式中, 只有hard
会直接将文件直接转为未提交commit
之前的状态- 一个已被跟踪的文件被改动了, 只要保存更改就会被放入保存区. 此时可以
- 使用
git checkout -- filename
来永久撤销文件修改. - 使用
git add
命令将更改放入暂存区
等待commit
.
- 使用
- 未放入
staged area
的修改不会被commit
. - 如果一个文件未被跟踪 (
untracked file
), 那么Git
系统只会提示你在git
文件夹中有一个未被跟踪的文件, 哪怕对齐进行修改git
也不会关心其修改内容. 只要add
一次就可以永久跟踪. show
显示的是commit
状态及细节,diff
显示的是文件的修改状态和细节- 在对文件修改时, 只会在当前
branch
进行修改, 在push
时, 也只会将此内容push
到远端的此 branch git
中的head
和branch
都是引用 (reference
), 其内存储的都是各个commit
的sha1
值. 引用都以文件形式存储在.git
目录中, 当git
工作时, 通过这些文件的内容判断整个仓库的结构.- 每个仓库只能有一个 head, branch 可以有多个
head
指向的branch
不能被删除, 必须签出到另一个 branch 方可删除git
中的branch
只是一个对commit
的引用, 删除branch
并不会删除任何commit
(不过如果一个commit
不在任何branch
上, 那么这个commit
就是一个野commit
, 其在一定时间后会被Git
的回收机制自动删除)checkout
的本质是移动head
到指定的commit
, 即如果后面跟的是branch
, 此命令会签出 此branch
所对应的commit
. 如果后面跟的是commit
, 那么直接签出该branch
, 比如git checkout 78a4bc
,git checkout HEAD^
,git checkout 78a4bc^
. 不过需要注意如果根据commit
值来签出, 那么会导致head
变为detached
状态, 哪怕签出的位置在某个branch
上也不行. 想离开这种detached
状态可以使用git checkout <branch name>
命令merge
会创建一个新的commit
来使两个branch
的最新commit
进行融合, 但是merge
会出现几种冲突情况:- 两个
branch
中的同一个文件的同一行被各自branch
修改了 (只能手动选择保留部分了) - 目标
commit
(需要被merge
的commit
) 与head
所指向的commit
并不存在分叉, 而是head
领先于目标commit
: 此时merge
不会创建一个新的commit
, 因为没有需要合并的, 什么也不会做 - 目标
commit
与head
所指向的commit
不存在分叉, 但是head
所指向的commit
落后于目标commit
: 此时merge
依然不会创建一个新的 commit(因为没哟需要合并的内容), 此时会将head
指向的commit
快速向前移动 (fast-forward
). 这其实非常常见: 本地没有提交, 但是同事开发了新内容并合并到了master
上, 本地pull
的时候会先 进行fetch
, 然后merge
, 此时merge
的目标commit
即领先于 head 指向的commit
, 这个时候就会进行fast-forward
)
- 两个
merge
后branch
不会被自动删除- 没有被
merge
的branch
在删除时会失败 (但是如果确认某个branch
完全没有作用了, 一定要删除, 那么可以将git branch -d
改为git branch -D
来强制删除) pull
=fetch
+merge
push
并不会上传head
到远端, 即远程仓库永远只会指向master
. 这也是为什么从远端clone
下来后在第一次使用时总是指向master
的.- 不是最新的几次提交不能用
git reset
. 不是最新的一次提交不能用git commit --amend
rebase
可以合并commit
, 修改之前某次commit
, 删除之前某次commit
, 属于 git 中的高深用法.- 在
git
中有两个偏移符号^
与~
,^
表示根据head
向左偏移,~
表示根据branch
向左偏移 tag
可以理解为 不可移动的branch
, 通常用来为项目节点做标记cherry-pick
: 把选中的commit
一个个合并
Git 常用命令
git help <command>
: 对 git 的某一命令查看帮助, e.g.git help config
git help --web log
: 在浏览器中查看git log
的用法git help --man log
: 在 man 中查看git log
的用法git -C path/to/repo
: 指定 repo 的路径进行相关 git 操作, 写脚本时非常有用(可以避免 cd)git ls-remote <url> --tags origin | cut -f 1
: 获取远程仓库 origin 分支最新的 commit 值git --git-dir=/path/to/repo/.git rev-parse origin/<targeted-banch>
: 获得本地仓库分支的最新 commit 值git symbolic-ref --short HEAD
: 获得当前分支名git rev-parse --abbrev-ref HEAD
: 获得当前分支名(同上)git clone
: 克隆仓库git clone <link> [foldername]
: 从远端链接拉取项目, link 可以为https
连接, 也可以为ssh
连接, 最后的 foldername 表示可以指定文件夹名称git clone -b master <link>
: 克隆远程仓库到本地, 并 checkout 到master
分支git clone -b 0.0.5 <link>
: 克隆远程仓库到本地, 并 checkout 到 tag0.0.5
上git clone --recursive <link>
: 递归克隆, 在项目包含子模块时非常有用git clone --depth=1 <link>
: 克隆深度为 1, 只克隆最后一条, 减少克隆时间git clone --bare <link>
: 裸克隆, 没有工作区内容, 不能进行提交修改, 一般用于复制仓库git clone --mirror <link>
: 镜像克隆, 也是裸克隆, 区别于包含上游版本库注册
git status
: 状态git status
: 查看当前branch
的当前状态与最近一次commit
相比, 暂存区 & 保存区 & 以及未跟踪文件的状态, 提交前一定要用git status -s
: 以短格式输出git status --ignore-submodules
: 忽略子模块git status --ignored
: 显示忽略的文件
git init
: 初始化git init
: 将当前目录直接作为git
的工作路径并生成一个.git
文件夹git init [repo name]
: 将repo name
作为工作路径并在repo name
文件夹下剩下一个.git
文件夹git init repo.git --bare
: 创建一个repo.git
的文件夹并将其作为 git 库, 其内直接包含.git
文件夹内的所有文件, 相当于去除了工作区
git config [range] [command] [option]
: 配置 git 环境range
: 有三种级别, system, global, local, sytem 针对当前系统所有用户的所有 repo, gloabl 针对当前用户的所有 repo, local 只针对当前 repo, 他们的关系是如果下一级的 config 没有对某项配置做自定义, 就自动引用上一级的 config 相关配置--system
: 将 config 配置写入/etc/gitconfig
--global
: 将 config 配置写入~/.gitconfig
文件--local
: 默认级别, 将 config 配置写入当前 repo 的.git/config
文件中
command
: 命令--list
: 列出当前 repo 的所有 config 信息 (如果使用了 global 则列出 global 的 config 信息)--unset
: 取消 config 中某项配置 (后跟 option), 也可以通过编辑.gitconfig
或config
文件来达到同样目的--unset-all
: 取消 config 中所有配置--remove-section
: 移除某组配置--rename-section
: 重命名某组配置
option
: 具体配置--user.name
: 设置用户名, 安装 git 必设置--user.email
: 设置用户邮箱, 安装 git 必设置--core.editor
: 设置 git 的默认编辑器, 默认为 vi 或 vim--merge.tool
: 设置 git 的合并工具alias.st status
: 设置 git 的某些快捷别名, e.g.git config --global alias.st status
的作用是让git st
指向git status
git config --global --unset user.name
: 删除相关配置, 可以是--global
, 也可以是--local
git config --global -e
: 编辑当前仓库配置文件, 等价于vim ~/.gitconfig
git config --global https.proxy http://127.0.0.1:1087
: 配置代理git config --global http.proxy http://127.0.0.1:1087
: 配置代理git push
: 推送本地仓库到远程git push origin test
: 将当前 branch push 到远程的test
分支上(其本质是提交本地分支test
指针到origin
, 相当于拷贝refs/heads/test
到远程引用refs/remotes/origin/test
并提交)事实上
git push
命令也可以进行push
, 不过git push
只能push
从远端pull
或者clone
下来的branch
, 对于由本地直接创建的branch
就无能为力了, 或者本地创建的仓库使用git push --set-upstream origin branch1
命令指定了本仓库对应的远程仓库分支, 这样也能直接使用git push
git push origin test -f
: 强制push
, 在本地仓库与远程仓库有差别被拒绝的时候但是自己很清楚的时候使用. 但是如果冲突发生在master
的话就不要用了. 很危险.git push origin <local branch1>:<remote branch2>
: 将本地branch1
推送到远程branch2
上remote branch2
不写的话表示将本地分支branch1
推动到远程同名branch
上local branch2
不写的话代表将空分支推送到远程branch2
上, 也就是表示删除远程branch2
以下四种书写方式效果是一样的:
git push origin master
git push origin master:master
git push origin master:refs/heads/master
git push origin refs/heads/master:refs/heads/master
git push -u origin HEAD
: 将当前分支名推送到远程同名分支(远程没有同名分支的话会自动创建)git push -u origin branch1
: 将 branch1 分支推送到远程同名分支(远程没有同名分支的话会自动创建)git push origin --all --force
: 将本地所有分支强制提交到远端git push --tags
: 推送所有tag
, 不推送commit
git push --follow-tags
: 推送commit
的同时会把当前branch
上的所有tag
进行推送git push --atomic origin <branch name> <tag>
: 将git push origin <branch name>
与git push <tag>
作为一个原子命令, 一旦原子命令中的任何一个失败, 则整个原子命令失败git push origin 9790eff:master
: 将本地9890eff
以前的所有commit
推送到远端git push origin --delete master
: 删除分支, 等价于git push origin :master
git push origin :<old name> | git push origin <new name>
: 重命名远程分支 (方法 1), 原理是先删除远程某分支, 然后将本地当前分支推送到新命名的远程分支上git push b_origin refs/remotes/a_origin/main:main
: 将a_origin
的main
分支推送到b_origin
的 main 分支上git push b_origin refs/remotes/a_origin/main:refs/heads/main
: 同上, 不过在b_origin
没有main
分支时会自动创建该分支
git fetch
: 从远端获取仓库对应分支的最新状态git fetch -a
: 从远端获取仓库所有分支的更新 (不合并任何分支)git fetch --all --prune --force --tags
git fetch origin
: 手动指定了要fetch
的remote
, 在不指定分支时通常默认为master
git fetch origin dev
: 指定远程remote
和FETCH_HEAD
, 并且只拉取该分支的提交git fetch origin branch1:branch2
: 从服务器拉取远程分支branch1
到本地为branch2
, 并使branch2
与branch1
合并git fetch b_origin main:refs/remotes/a_origin/main
: 将b_origin
的main
分支拉取到本地a_origin
的main
分支上
git pull
: 从远端拉取仓库最新状态并与本地仓库合并git pull -a
: 从服务器远端拉取仓库的所有分支的更新, 并将当前分支对应的远程分支的更新合并到本地当前分支上 (不合并其他分支)git pull orign test
: 从服务器拉取远端名为test
的branch
并与本地当前的branch
合并 (这个命令适用于在本地git branch <name>
或git checkout -b <name>
刚建立了一个新的本地分支, 然后从服务器的指定分支拉取commit
到本地此新分支上)git pull origin master --rebase
: 以变基方式拉取远端主分支到本地master
分支, 主要用于第一次拉取远端分支git pull origin branch1:branch2
: 从服务器远端拉取branch1
分支合并到本地的branch2
分支, 如果本地没有branch2
分支的话则新建. 然后将拉取到的分支合并到当前所处的分支上git pull origin master:master
: 从服务器拉取远程master
到本地master
上, 然后合并, 然后将 master 分支 merge 到当前所处的分支上. 这个比git fetch
多了一步 (合并master
到本分支), 因此要慎用, 最好用git fetch
, 然后自行判断git pull origin master:master --rebase
: 与上一种功能类似, 不过是将当前分支rebase
到master
分支上
git remote
: 远程仓库git remote -v
: 查看远程仓库地址git remote add origin <url>
: 在没有远程仓库的基础上添加远程仓库地址git remote set-url origin <url>
: 在有 origin 的基础上直接重新设置远程仓库地址git remote rm origin
: 删除远程仓库地址git remote show origin
: 查看远程仓库信息 (比如 push 与 pull 地址, 远程仓库当前 head 指向, 远程仓库当前分支)git remote rename oldname newname
: 重命名远程仓库git remote remove origin
: 移除远端跟踪
git show
: 查看最近一次commit
(head
所指向的commit
) 修改的文件和内容git show --stat
: 查看最近一次commit
的统计信息 (修改了多少处)git show 5e68b0d8
: 查看sha
值为5e68b0d8
的commit
修改内容git show 5e68b0d8 a.txt
: 查看sha
值为5e68b0d8
的commit
中 a.txt 文件的具体修改情况
git diff
: 显示目前的保存区与最近一次commit
的原工作目录相比有什么差异. 即, 在git add
后会向暂存区提交什么内容git diff --staged
: 查看暂存区与最近一次commit
的原工作目录相比有什么差异. 即, 这条指令可以让你提前知道你commit
会提交什么内容. 这个命令与git diff --cached
完全等价git diff master..branch
: 比较master
与branch
之间的不同git diff 0023cdd..fcd6199
: 比较两个commit
之间的不同git diff master..master~2 -- README.md
: 比较两个commit
之间的README.md
不同git diff -- README.md
: 查看当前分支README.md
文件的变动git diff adt312d
: 查看adt312d
这个commit
与当前最新commit
的异同(从 adt312d 到 HEAD 中间有什么变化)git diff E..A^ | git apply
: 先获取从 E 到 A 的前一个节点之间的变化, 然后这个改动就是这几个 commit 的逆操作, 使用git apply
将其应用到代码上, 然后再add
commit
git diff A..B
: 对比AB
两个提交的差异git diff A...B
:AB
两次提交的共同祖先和B
之间的 diffgit diff --theirs
: 在合并冲突时表示当前冲突相对于 theirs 的变化
git ls-files
: 列出本分支下所跟踪的文件列表git add
: 添加改动到暂存区 (staged area
), 虽然add
后添加的是文件名, 但实际上添加的是改动 (如果a.txt
改动后被add
, 然后再次被改动a.txt
的另一处, 那么在git status
时会警告a.txt
既在暂存区又不在)git add./README.md
: 仅暂存当前目录下的README.md
文件git add <file1> <file2>...
: 一次暂存多个文件git add.
: 提交本路径下的全部更改 (新文件, 修改文件, 删除文件)(会忽略.gitignore
中列出的新增文件)git add -A
: 同git add.
, 不过添加的是本仓库的所有路径下的更改 (会忽略.gitignore
中列出的新增文件)git add -u
: 只提交已经跟踪文件的修改 (不理会新文件)git add --ignore-removal.
: 只提交新文件与修改文件 (不理会删除文件)git add --all -- ':!path/to/file1' ':!path/to/file2' ':!path/to/folder1/*'
: 排除指定路径下的改动(path 可以使用/
表示 repo 的根目录)git add -- . ':!path/to/file1' ':!path/to/file2' ':!path/to/folder1/*'
: 排除指定路径下的改动git add --patch filename.txt
: 暂存一个文件的一部分, 会打开交互模式, 使用 s 进行存储操作git add -N filename.txt
: 暂存一个新文件的一部分, 会打开交互模式, 使用 e 手动选择需要添加的行
git merge
: 合并分支git merge test
: 将名为test
的branch
合并到当前head
所指向的分支git merge --abort
: 在出现merge conflict
状况时放弃此次merge
, 会恢复到merge
之前的状态.git merge --continue
: 解决冲突后继续merge
git mergetool
: 在合并出现问题时使用此工具进行手动合并git checkout --conflict=merge file
: 重新标记文件为unmerged
(待合并状态)
git merge develop -q
: 以安静模式合并, 吧 develop 分支合并到当前分支并不输出任何消息git merge develop --no-edit
: 合并时使用默认的合并消息git merge develop --no-commit
: 合并分之后不进行提交
git cherry-pick
: 挑选commit
git cherry-pick commit1 commit2 commit3
: 将三个commit
合并入本branch
git cherry-pick commit1 commit2 commit3 --no-commit
: 将三个commit
的内容放入本branch
的暂存区但是先不合并git cherry-pick 00b44e4..b135951
: 连续 commitgit cherry-pick -x commit1
: 在合并时将commit1
的原有作者信息进行保留
git commit
: 提交通过add
命令放入暂存区的改动git commit -a
: 提交全部更改 (默认将所有修改文件及删除文件添加进暂存区)git commit -m "message"
: 使用message
作为commit
的标题直接提交git commit --amend
: 对最新的commit
进行修改 (此操作不会直接在原commit
上进行修改, 而是将新修改内容与最新commit
内容进行融合, 据此创建一个新的commit
并进行替换)git commit --amend --no-edit
: 在amend
的基础上, 不进入修改 message 界面git commit --amend --reset-author
: 默认情况下amend
并不会重置第一次author
的时间, 使用--reset-author
可以重置author
时间为当前时间git commit --author "HanleyLee <hanley.lei@gmail.com>"
: 指定 author 的方式进行 commitGIT_COMMITTER_NAME="HanleyLee" GIT_COMMITTER_EMAIL="hanley.lei@gmail.com" git commit --author "HanleyLee <hanley.lei@gmail.com>"
: 同时设置author
与committer
git commit --allow-empty-message
: 允许提交空消息, 通常必须有消息git commit -v
: 在填写信息的界面显示所有变动 (diff
格式的)
git stash
: 将保存区与暂存区的文件 (未commit
的) 临时放入一个空间 (注意: 未跟踪的文件不会被stash
), equal togit stash save
/git stash push
git stash save "test"
: 保存时添加注释(already depreated, usegit stash push
)git stash push
: 将保存区与暂存区的文件git stash push -m "test"
: 将保存区与暂存区的文件, 对 stash 命名git stash list
: 查看当前保存列表git stash show stash@{0}
: 显示更改的相关文件git stash show -p stash@{0}
: 显示所有的更改 (更加详细)git stash pop
: 将stash
空间保存的文件还原到保存区中git stash pop stash@{1}
: 恢复指定 stash, 具体编号可以通过git stash list
查找git stash apply
: 与 pop 命令相同, 不过不会从 stash 列表中移除git stash clear
: 清空所有保存的 stashgit stash drop stash@{0}
: 清除指定 stashgit stash drop
: 清除最近一次git branch
分支管理git branch test
: 从head
所指向的commit
处创建一个名为test
的新的branch
git branch branch1 origin/branch1
: 从本地下载的远程branch1
处在本地建立一个branch1
分支git branch -r
: 显示本地所有分支git branch -a
: 显示本地及远程所有分支git branch -r
: 显示远程端所有分支git branch -vv
: 查看本地分支所关联的远程分支git branch --set-upstream-to=origin/branch1 branch1
: 设置本地 branch1 所追踪的远程分支为origin/branch1
git branch --set-upstream-to=origin/branch1
: 设置本地当前 branch 所追踪的远程分支为origin/branch1
git branch -u origin/branch branch
: 同--set-upstream
, 也是追踪远程分支git branch --unset-upstream
: 移除跟踪git branch -d test
: 删除名为test
的branch
git branch -D test
: 强制删除名为test
的branch
(即使没有被 merge 的分支也可以删掉, 如果删除之后想恢复, 那么使用git checkout -b branch-name hash
即可)git branch -r -d origin/hanley
: 删除本地已经下载的远程分支, 同时要执行以下两个命令中任意一个:git push --delete origin <branch name>
: 使用删除命令直接删除远程branch
git push origin:<branch name>
: 使用推送命令将一个空branch
推送到远程以达到删除该 tag 的效果
git branch -m <old name> <new name>
: 重命名本地分支git branch -M <old name> <new name>
: 强制重命名本地分支git branch -f <branch> <commit>
: 重新定义 branch 的起始节点到某个commit
git branch -m <old name> <new name>
|git push origin:<old name>
|git push --set-upstream origin <new name>
: 重命名远程分支 (方法 2), 先本地重命名, 然后删除远程某分支, 最后推送并设定推送到的远程branch
名git branch --merged
: 查看已经合并的branch
git branch --no-merged
: 查看未合并的branch
git branch --merged | xargs git branch -d
: 删除已经合并的branch
git branch --show-current
: 输出当前分支, 同git rev-parse --abbrev-ref HEAD
git branch --contains <commit-id>
: 列出所有包含 commit 的分支git branch --contains dcc5ae4 | grep -E '(^|\s)branch$' &>/dev/nul
: 过滤包含 commit-id 的分支(可以用来判断一个分支是否包含某个 commit)git branch $(git symbolic-ref --short HEAD) --contains $COMMIT_ID
: 限定结果只展示当前分支git branch | grep -o -m1 "\b\(master\|main\)\b"
: 打印默认分支(master or main)git reflog show --data=iso master
: 查看本地master
分支的创建时间git switch <branch1>
: 切换分支
git merge-base
: Find as good common ancestors as possible for a merge.git merge-base --is-ancestor $COMMIT_ID $BRANCH
: 判断分支是否包含指定 commit, 比git branch $BRANCH --contains $COMMIT_ID
更好
git checkout
: 签出git checkout myfile.txt
: The contents of myfile.txt will be copied from thestaging area
to theworking directory
git checkout .
: Same as above, but apply to all current directorygit checkout HEAD myfile.txt
: Take the version of myfile.txt that is in head’s parent and copy it to both the staging area and the working directorygit checkout 3dbs22 a.txt
: Same as abovegit checkout test
: 签出名为test
的branch
对应的commit
(work dir
与staged area
的改动不会被重置, 可以使用-f
参数进行重置)git checkout -f master
: 强制切换到 master, 未保存的改动(包括work dir
与staged area
)会被丢弃git checkout HEAD^^
: 将HEAD
向左两位的commit
签出 (即倒数第三位)git checkout head~3
: 将head
向左三位的commit
签出 (即倒数第四位)git checkout 3d122b
: 将sha
值为3d122b
的commit
签出, 此时会导致head
变为detached
状态, 想离开这种detached
状态可以使用git checkout <branch name>
命令git checkout -b test
: 创建一个名为test
的branch
并签出到该branch
对应的commit
git checkout -b test origin/test
: 在本地创建名为test
的branch
并跟踪远端的test
分支git checkout -t origin/dev
: 在本地创建名为dev
的branch
并跟踪远端的dev
分支, 通常是在本地没有远程分支才会本命令git checkout --detach
: 使head
与branch
分离, 使head
直接指向commit
git checkout --conflict=diff3 test.txt
: 将文件重置回冲突状态, 适用于 merge 时发生冲突后没有完全解决时被一些其他工具将文件标记为了解决git checkout --conflict=merge test.txt
: 将文件重置回冲突状态git checkout --ours test.txt
: 在合并冲突时选择ours
作为解决方案git checkout --theirs test.txt
: 在合并冲突时选择theirs
作为解决方案
git blame
: 责怪~git blame <filename>
: 查看某个文件的修改历史记录, 含时间, 作者, 以及内容git blame -L 11,12 <filename>
: 查看谁改动了某文件的 11~12 行git blame -L 11 <filename>
: 查看 11 行以后的所有改动人git blame -l <filename>
: 显示完整的 hash 值git blame -n <filename>
: 显示修改的行数git blame -e <filename>
: 显示作者邮箱git blame -enl -L 11 <filename>
参数组合查看修改者
git restore
: 重置git restore <filename>
: 将保存区的此文件更改全部重置, 降级! 与git checkout -- <filename>
功能相同git restore --staged <filename>
: 将暂存区文件转移至保存区, 降级!git checkout -- *
git checkout -- *.md
git checkout -- 123.md 345.md
git reflog
: head 记录git reflog
:reference log
的缩写. 可查看Git
仓库的head
的所有移动记录. 可以在误删 branch 等情况下使用git reflog master
: 查看关于master
的所有head
的移动记录.git reset --hard HEAD@{3}
: 恢复到指定节点状态
使用
git reset --hard hash
也可回退到 reflog 对应的节点上git rm
: 移除git rm <filename>
: 删除对文件的跟踪, 并删除本地文件 (在工作区中保留, 但从版本库中移除, 如果已经放入暂存区的话会报错)git rm --cached <filename>
: 取消对某个文件的跟踪. 而不删除本地文件(在工作区中保留, 但从暂存区和版本库中移除)git rm -f <filename>
: 删除对文件的跟踪, 并删除本地文件 (已添加到暂存区时使用).f
是强制的意思git rm -r --cached <foldername>
: 取消对某个文件夹的跟踪.r
为递归的意思.git rm -r *
会将当前目录下的所有文件与子目录删除git rm -rf.
: 清除当前目录下的所有文件, 不过不会删除.git
目录-n
: 所有的rm
命令后面加上此命令后, 不会删除任何东西, 仅作为提示使用
git clean <command>
: 清理未被tracked
的文件,git reset
只能让跟踪的文件回复到某个版本状态, 对于未跟踪的文件无能为力, 如果想要完全移除未跟踪的文件, 那么就要使用git clean -df
, 此命令常与git reset
配合使用 (默认情况下,git clean
命令只会移除没有忽略的未跟踪文件, 如果也需要移除已被gitignore
忽略的文件, 则需要加x
)-f
: 强制删除. 如果Git
配置变量clean.requireForce
未设置为false
,git clean
将拒绝删除文件或目录, 除非给定-f
,-n
或-i
.-f <path>
: 删除指定路径下untracked files
-d
: 除了未跟踪的文件之外, 还要除去未跟踪的目录.-X
: 仅删除当前目录下gitignore
里忽略的文件, 那些既不被git
版本控制, 又不在gitignore
中的文件会被保留.-x
: 不使用gitignore
的忽略规则, 删除本路径下所有的untracked files
-n
: 将此命令加在上面三个命令前, 先看看会删除哪些文件 (相当于演习一遍). e.g.git clean -n -xfd
-i
: 使用交互式删除, 每一个文件的删除都有提示, 更加安全
git tag
: 不可移动的标识点, 通常用来作为里程碑标记, 最广泛的使用就是作为版本标记git tag
: 显示所有tag
git ls-remote --tags origin
: 列出远程所有标签(不加 origin 也可以)git tag <tag name>
: 为最新 commit 的创建 taggit tag <tag name> <commit name>
: 为之前的某个 commit 点创建 taggit show <tag name>
: 显示指定 tag 信息git tag -d <tag name>
: 删除本地的指定 tag; 如果想要删除远程的 tag, 需要先在删除本地 tag, 然后使用:git push origin --delete tag <tag name>
: 使用删除命令直接删除远程tag
(或使用git push origin --delete tag <tag name>
)git push origin:refs/tags/<tag name>
: 使用推送命令将一个空 tag 推送到远程以达到删除该 tag 的效果
git push origin <tag name>
: 推送指定 tag 到远程git push origin --tags
: 推送所有本地 tag 到远程git tag -l | xargs git tag -d
&&git fetch origin --prune
: 先删除本地所有分支, 然后从远端拉取所有分支, 适用于远端的 tag 被修改但是本地 tag 仍然是旧的git tag -l v1.*
: 筛选符合条件的 taggit tag -a v1.4 -m "my version 1.4"
: 创建含标注的 tag, 并为此标注直接添加信息 (标注可通过 git log 查看)git tag -a v1.2 9fceb02
: 为之前的提交打 tag, 会进入填写 message 界面git fetch --tags
: 拉取远程所有 tag
git revert
: 添加与之前commit
完全相反的commit
git revert HEAD^
: 增加一条与当前head
指向的commit
的内容完全相反的commit
. 从而达到”中和”的效果以对其进行撤销. 用在错误内容已经合并在master
但是需要修改的时候.git revert OLDER_COMMIT^..NEWER_COMMIT
git reset
: 重置到某个commit
(第一个参数是提交的 SHA-1, 默认是 HEAD, 第二个参数如果不写则是整体重置, 否则只重置单个文件)git reset a.txt
: 将文件 a.txt 从HEAD
中还原到staged area
, 然后再退回到work dir
中 (默认使用的是mixed
)git reset --mixed HEAD a.txt
: 是上一个命令的全称git reset HEAD./README.md
: 仅重置某文件到HEAD
git reset --hard HEAD^^
:HEAD^^
表示需要恢复到的commit
, 因此这个命令表示将 track 的文件直接恢复到上上一个commit
, 其后的所有commit
全部丢弃 (如下图所示, 虽然commit
不被任何branch
指向了, 但是Git
不会立刻删除它, 还是可以通过sha1
值来复原的), 一般与 git clean 联合使用git reset 17bd20c
: 相当于把HEAD
移到了17bd20c
这个commit
, 而且不会修改work dir
中的数据, 所以只要add
再commit
, 就相当于把中间的多个commit
合并到一个了.
git rebase
: 变基git rebase master
: 在branch
上执行此命令. 将branch
上从与master
交叉的commit
之后的所有commit
依次提交到master
最新commit
之后 (就是将节点 5, 6 的内容在master
分支再次提交一次). 如果想指定基础点参考 这里
git rebase -i <commit>
: 交互式变基, 可合并 commit, 剔除 commit 等git rebase -i HEAD~10
: 将当前 head 向前数 10 个的所有 commit 进行变基git rebase --continue
: 解决冲突后, 解决冲突, 并git add
, 然后使用本命令可继续 rebase 操作, 不需要git commit
git rebase --abort
: 产生冲突时, 放弃本次 rebase, 恢复到 rebase 之前的状态git rebase origin/main
: 变基对象为 origin 远程分支
git rebase 的作用是变基, 在合并时可以先切换到 branch1, 然后对 master 进行 rebase, 没有冲突的话直接完成操作, 有冲突的话先解决冲突, 然后
git add
, 然后git rebase --continue
, 这样 branch1 的 commit 就完全挪到了 master 之上, 这时再切换到 master 分支上, 使用git rebase branch1
(或git merge branch1
), 可以达到fast-forword
的效果. 最后可以 push 到远程仓库, 这样自己的新的 commit 就在 master 上整齐地排列着了.git rerere
: 自动解决冲突, 需要提前设置git config --global rerere.enabled true
git log
: 显示commit
的提交记录 (并不会显示add
操作)--patch
: 是git log -p
的全写, 可以查看每个commit
的细节--stat
: 查看每次文件提交更改的统计信息 (修改了多少处)--oneline
: 以一行的格式查看本branch
的commit
记录 (仅 sha2, branch, commit title 以及顺序信息)--merges
: 只显示合并的commit
--no-merges
: 不显示合并的commit
--graph
: 图表形式 (竖线, 斜线) 显示 commit 顺序及关系--decorate
: 装饰作用, 显示当前 head, tag, branch 的效果--all
: 显示所有commit
信息, 否则可能会只显示本branch
的commit
, 省略其他分支的commit
-S Swift
: 显示关键字中有Swift
的 commit-[number]
: 显示最近多少次的commit
记录--pretty=format:"[option]"
: 以固定格式输出commit
信息%H
: 提交的完整哈希值%h
: 提交的简写哈希值%T
: 树的完整哈希值%t
: 树的简写哈希值%P
: 父提交的完整哈希值%p
: 父提交的简写哈希值%an
: 作者名字%ae
: 作者的电子邮件地址%ad
: 作者修订日期 (可以用 –date= 选项 来定制格式)%ar
: 作者修订日期, 按多久以前的方式显示%cn
: 提交者的名字%ce
: 提交者的电子邮件地址%cd
: 提交日期%cr
: 提交日期 (距今多长时间)%s
: 提交说明$d
: decorate 效果 (显示当前 head, tag, branch)%C(<color>)
: 为跟在后面一个参数设置颜色或字体, e.g.git log --pretty=format:"%C(bold red)%h%Creset -%C(bold green)%d %C(bold yellow)%s %Creset- %C(red)%cd %Creset- %C(dim green)%an" --date=format:'%Y-%m-%d %H:%M:%S' --graph
- 一个颜色+一个内容
- 颜色以%C 开头, 后边接几种颜色, 还可以设置字体, 如果要设置字体的话, 要一块加个括号
- 能设置的颜色值包括: reset(默认的灰色), normal, black, red, green, yellow, blue, magenta, cyan, white.
- 字体属性则有 bold, dim, ul, blink, reverse.
- 内容可以是占位元字符, 也可以是直接显示的普通字符
--date=<option>
: 通过预置的选项设置 log 中 commits 的日期格式relative
: 显示距当前时间多少, e.g. “2 hours ago”local
: 显示本地时间, e.g “Wed Feb 26 18: 03: 14 2020”default
: 显示当前时区及时间, e.g. “Wed Feb 26 18: 03: 14 2020 +0800”iso
: 以 ISO 8601 格式显示时间rfc
: 以 RFC 2822 格式显示时间short
: 只显示日期, e.g. “2020-02-26”raw
: 显示 git 的原始格式, e.g. “1582711394 +0800”
--date=format:'<option>'
: 通过占位符设置 log 中 commits 的日期格式 e.g.--date=format:'%Y-%m-%d %H:%M:%S'
%a
: Abbreviated weekday name%A
: Full weekday name%b
: Abbreviated month name%B
: Full month name%c
: Date and time representation appropriate for locale%d
: Day of month as decimal number (01 – 31)%H
: Hour in 24-hour format (00 – 23)%I
: Hour in 12-hour format (01 – 12)%j
: Day of year as decimal number (001 – 366)%m
: Month as decimal number (01 – 12)%M
: Minute as decimal number (00 – 59)%p
: Current locale’s A.M./P.M. indicator for 12-hour clock%S
: Second as decimal number (00 – 59)%U
: Week of year as decimal number, with Sunday as first day of week (00 – 53)%w
: Weekday as decimal number (0 – 6; Sunday is 0)%W
: Week of year as decimal number, with Monday as first day of week (00 – 53)%x
: Date representation for current locale%X
: Time representation for current locale%y
: Year without century, as decimal number (00 – 99)%Y
: Year with century, as decimal number%z, %Z
: Either the time-zone name or time zone abbreviation, depending on registry settings; no characters if time zone is unknown%%
: Percent sign
配置完自己喜爱的配色后, 使用可以为 git 命令定义别名方便下次使用, e.g.
git config --global alias.lg "log --pretty=format:'%C(bold red)%h%Creset -%C(bold green)%d %C(bold yellow)%s %Creset- %C(red)%cd %Creset- %C(dim green)%an' --date=format:'%Y-%m-%d %H:%M:%S' --abbrev-commit --graph"
git log --oneline --graph --all
: 以图表, 简洁形式显示 commit 信息git shortlog -sn
: 列出提交者贡献数量, 只会打印作者和贡献数量git shortlog -n
: 以提交贡献数量排序并打印出 messagegit shortlog -e
: 采用邮箱格式化的方式进行查看贡献度
git bisect
: 黑魔法, 使用二分法查看哪一个 commit 产生的 buggit bisect start [end] [start]
: 启动查错,end
是最近的提交,start
是更久以前的提交. 启动之后会定位到end
&start
的中点git bisect good
: 标记此 commit 为正确的, 意味着问题是在后半段产生的git bisect bad
: 标记此 commit 为错误的, 意味着问题是在前半段产生的git bisect reset
: 完成二分查找, 回到最近一次代码提交
git update-ref -d refs/remotes/origin/HEAD
: removeorigin/HEAD
git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/master
: createorigin/HEAD
git symbolic-ref refs/remotes/origin/HEAD
: 获得远程默认分支, master 或 maingit symbolic-ref --short -q HEAD
: 获得本地当前分支git archive [option] [branch/commit] [from path]
: 导出代码 (可支持下载远程仓库指定文件夹, 不支持 GitHub)--format tar.gz
: 导出的格式, 使用git archive --list
可以查看当前 git 所支持的所有格式; 如不指明, 则使用 –output 的文件名推断文件格式--output "./output.tar.gz"
: 将存档写入<file>
而不是 stdout.--remote git@192.168.1.203:iOS/ZRCombineViewer.git
: 指定远程仓库位置, 如不指定则导出当前目录下仓库的代码--exec=<git-upload-archive>
: 与 –remote 一起用于指定 git-upload-archive 远程端的路径.--verbose
: 实时显示最新进展--prefix=<prefix>/
: 在所有文件命前加入前缀
bash// 写入压缩文件 git archive --remote git@192.168.1.203:iOS/ZRCombineViewer.git -o test.zip master fastlane/actions fastlane // 下载后解压到指定文件夹 git archive --remote git@gitlab.com:HanleyLee/helloworld.git --format=tar --prefix=junk/ master | (mkdir ~/Desktop/t1 && cd ~/Desktop/t1/ && tar xf -)
git --git-dir=$HOME/projects/foo/.git --work-tree=$HOME/projects/foo status
: 查看某个文件夹的 git 状态git remote set-head origin master
: 如果使用git branch -a
时发现没有origin HEAD
, 那么可以使用本命令手动添加 HEADgit remote set-head origin -d
: 与上面相反, 此命令可以删除origin HEAD
committer
和 author
的区别
author
是做出修改的人, committer
是最后提交到 git
中央仓库的人
.gitignore
文件
git 是根据 .gitignore
文件来判断是否监视一个文件 (夹) 的, 如果文件在 .gitignore
中被列出, 那么即使该文件被添加, git 也不会提示对其进行跟踪, 如果一个文件夹下被加入到 .gitignore
文件, 那么其自身及其内文件 (夹) 都不会被跟踪.
如果在添加 .gitignore
文件之前已经不想同步的内容已经被 git 跟踪了, 那么需要将其移除出跟踪区, 使用 git rm --cached <filename>
.
使用 git clean -fX
可以将被忽略的文件全部删除 (一般不用)
不同步指定文件
.gitignore
文件可以让 git
忽略某些文件, 或者在忽略全部文件的情况下不忽略某些文件
在没有
.gitignore
的情况下创建一个新文件touch.gitignore
# 忽略根目录及子目录下名为 `secret.md` 的文件
secret.md
## 忽略根目录及子目录下 `config` 文件夹下的 `secret.md` 文件
config/secret.md
# 忽略根目录及子目录下 config 下的 Markdown 文件
config/*.md
# 忽略根目录及子目录下的 build 文件夹
build/
# 忽略根目录及子目录下的 build 文件及文件夹
build
# 忽略当前目录的 build 文件
/build
只同步指定文件
touch.gitignore
# 忽略根目录下的所有文件及文件夹
/*
# 同步名为 normal.md 的文件, 但是如果文件夹未被同步, 那么文件夹内的此文件不会被 git 跟踪到, 也自然不会被同步
!normal.md
# 同步根目录下的 `config` 文件夹及其内文件 (夹)
!/config
如果需要只同步子文件夹下的某个文件, 有两种方法
- 先设置同步子目录
- 然后设置不同步子目录所有内容
- 再设置同步子目录指定文件
/*
!/config
/config/*
!/config/normal.md
全局忽略文件
git config --global core.excludesfile.gitignore_global
- 在本地用户根目录下创建
.gitignore_global
文件, 在其中设置需要全局忽略的文件类型 (下面的忽略按需使用)
# "#"是.gitignore_global 中的注释行
# Compiled source
*.pyc
*.com
*.class
*.dll
*.exe
*.o
*.so
# Packages
# it's better to unpack these files and commit the raw source
# git has its own built in compression methods
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip
# Logs and databases
*.log
*.sql
*.sqlite
# OS generated files
.DS_Store*
ehthumbs.db
Icon?
Thumbs.db
git diff 信息理解
- 被比较的文件:
diff
命令会对两个文件进行比较, 一个文件被设定为a
, 另一个被设定为b
- 元数据: 刚开始的
2a3483c
与53ed7d1
代表两个文件的hashes
. 后面的100644
代表这是一个普通文件, 如果是10755
则代表是一个可执行文件,120000
代表是符号链接. - a/b 文件标识: 使用
-
作为a
的标志, 使用+
代表b
的标志 - 区块头:
-
代表来自文件a/Test/stash.txt
,1
代表从第一行开始,2
代表从第一行开始的2
行代码. 因此整句连起来:a
文件 (旧文件) 从第一行开始的2
行内有数据被改动,b
文件 (新文件) 从第一行开始的3
行内有数据改动 - 改动:
+
代表是新文件的改动. 如果是-
则是旧文件的改动, 而旧文件的改动就是删除内容, 新文件的改动就是增加内容
rebase 使用
使用交互式 rebase 修改 / 删除之前某次提交的 commit
git rebase -i 目标 commit
bashgit rebase -i HEAD^^ // 在 git 中有两个偏移符号 ^ 与 ~, ^ 表示根据 head, ~表示根据 branch 向左偏移. 这个命令表示将当前 commit rebase 到 HEAD 之前 2 个的 commit 上.
在编辑界面中指定需要操作的
commits
将
pick
修改为edit
(含义是使用这个commit
, 但是停下来等待修正) 『使用pick
代表选取, 如果直接删除这一行就代表跳过这个commit
, 那就是把这个commit
删除了』退出编辑界面
- 根据提示修改最后使用
amend
进行修正提交 - 操作完成之后用
git rebase --continue
来继续rebase
过程各个commit
回复到原位
git rebase –onto 撤销历史 commit
如上图所示, git rebase commit3
会将 4
与 5
自动链接到目标 commit 3
之后, 因为 rebase
的起点是 Git
自动指定的, 起点判定为当前 branch
与要 rebase
到的 branch
的交点, 在此例中就是 2
. 因此 2
之后的 commit
都会被 rebase
到 3 之后.
git rebase --onto commit3 commit4 branch1
// 此命令有三个参数, 依次为目标 commit, 起点 commit, 操作 branch
// 在上图中, 就是将起点 commit 之后的 5 放入目标 commit 3 之后.
通过这一特性可以选择性地删除 commit
git rebase --onto HEAD^^ HEAD^ branch1
// 以当前 head 指向 commit 的前一个 commit 为起点, 将起点之后的 commit 3 提交到当前 head 指向 commit 的前 2 个 commit 上. 这样就达到了剔除 commit 2 的目的
合并同一 branch 多个 commit
目标: 将 123
与 2
合并
使用
git log --oneline
查看当前branch
的commit
记录使用交互式变基,
git rebase -i dc8d
, 修改2
与123
的pick
为squash
(也可以用fixup
, 代表丢弃子commit
名称)- 保存退出并并根据提示为新
commit
赋予名称
使用 --depth
保证本地只有最新的 commit
我们有时可能只需要最新的一次 commit
(比如出于硬盘空间考虑), 这个时候有以下两种办法:
- 在
clone
时使用git clone --depth 1 url
- 如果已经
clone
了, 那么需要多步 (参考自 stackoverflow)git pull --depth 1
git reflog expire --expire=all --all
git tag -l | xargs git tag -d
git stash drop
git gc --prune=all
git 辅助工具
gitup
git 仓库批量拉取更新
安装
brew install gitup
常用命令
gitup --help
: 查看 gitup 帮助信息gitup
: 拉取更新所有被add
到书签的仓库gitup.
: 更新当前路径下的所有仓库--depth <num>
: 指定递归深度, 默认为 3
gitup ~/repos/foo ~/repos/bar ~/repos/baz
: 指定多个路径进行批量拉取更新 (默认对每个路径递归 3 层查找所有存在的 repo)gitup -a ~/repos/foo ~/repos/bar ~/repos/baz
:--add
, 将多个仓库添加到 gitup 的书签中, 便于使用gitup
命令直接一键更新gitup -l
:--list
, 列出gitup
目前所有add
的仓库gitup -b ~/.config/gitup/bookmarks
:--bookmark-file
, 自定义指定书签文件gitup -d ~/repo
:--delete
, 删除已经add
的仓库gitup -n
:--clean
,--cleanup
, 删除路径已经变更的仓库的书签gitup -c
:gitup --current-only
, 默认情况下 gitup 将会拉取远端所有分支, 使用此命令可以只更新当前分支gitup -f
:gitup --fetch-only
, 默认情况下会pull
, 此命令会只fetch
gitup -p
:gitup --prune
: 默认情况下会在本地保留远端已经删除的branch
, 此命令会保持远端与本地端branch
完全一致gitup -e 'echo 123'
: 对所有的 repo 执行echo 123
这个命令gitup -e 'bash -c "echo 123 && echo 456"'.
: 使用bash -c
的目的是可以使用&&
语法
diff-so-fancy
git diff 高亮优化显示
安装
brew install diff-so-fancy
配置
// Configure git to use d-s-f for *all* diff operations
git config --global core.pager "diff-so-fancy | less --tabs=4 -RFX"
git config --global color.ui true
git config --global color.diff-highlight.oldNormal "red bold"
git config --global color.diff-highlight.oldHighlight "red bold 52"
git config --global color.diff-highlight.newNormal "green bold"
git config --global color.diff-highlight.newHighlight "green bold 22"
git config --global color.diff.meta "11"
git config --global color.diff.frag "magenta bold"
git config --global color.diff.commit "yellow bold"
git config --global color.diff.old "red bold"
git config --global color.diff.new "green bold"
git config --global color.diff.whitespace "red reverse"
icdiff
安装
brew install icdiff
使用
function gdf() {
params="$@"
if brew ls --versions scmpuff > /dev/null; then
params= `scmpuff expand "$@" 2>/dev/null`
fi
if [$# -eq 0]; then
git difftool --no-prompt --extcmd "icdiff --line-numbers --no-bold" | less
elif [${#params} -eq 0]; then
git difftool --no-prompt --extcmd "icdiff --line-numbers --no-bold" "$@" | less
else
git difftool --no-prompt --extcmd "icdiff --line-numbers --no-bold" "$params" | less
fi
}
scmpuff
安装
brew install scmpuff
echo "eval "$(scmpuff init -s)"" >> ~/.zshrc
使用
gs
: 显示当前所有文件状态, 类似于git status
git add 2 3 5-7
: 按照gs
的序号结果进行add
GitHub
GitHub(或其他 git 管理平台) 使用流程
- 在
GitHub
或者其他仓库管理平台创建一个仓库. 并复制仓库地址 - 在终端中使用
git clone
将远程仓库下载到本地 - 在开发时将自己仓库创建出一个分支用于自己开发新功能.
- 新功能开发完毕后将 branch 上传到中央仓库让同事进行检查, 如果有问题的话继续修改直至没有问题. 如果没有问题的话就
checkout
到本地仓库的master
pull
以使本地master
与远端master
保持同步merge
自己的branch
到本地master
,push master
到远端
- 实际上为了保证项目的安全, 中大型项目的远端仓库
master
都是被禁止直接push
的, 因此步骤 4 的流程就会变成:- 让同事检查是否有问题, 没有问题就提交通过远端的
branch
提交pull request
(pull request
是对于master
分支来说的, 希望master
能够pull
本branch
) - 成功
pull request
后删除本branch
- 让同事检查是否有问题, 没有问题就提交通过远端的
连接方式
目前 GitHub
有两种连接方式, HTTPS
连接与 ssh
连接, 在 clone
时要选择对应的链接.
特点
- 本账户向本账户下仓库提交代码可以直接使用
https
或者将自己电脑生成的ssh key
加入到GitHub
账户. - 本账户使用
HTTPS
方式向另一账户下的仓库提交代码需成为对方账户的collaborator
. - 本账户使用
ssh
方式向另一账户的仓库提交代码需要将本账户所在电脑生成的ssh key
加入到对方账户. ssh
方式连接在每次push
时无需再每次访问时输入密码- 如果
GitHub
账户使用了二重验证还希望使用HTTPs
那么必须使用access token
作为密码进行登录.
SSH 连接方式
- 在终端使用
ssh-keygen
方式生成 ssh key - 将
pub
公钥加入到 GitHub 账户中 - 在仓库页面选择
ssh
链接进行复制 - 在本地文件夹进行
clone
查看 / 更改连接方式
- 通过
git remote -v
查看当前与远程的连接方式 - 修改为
HTTPs
:git remote set-url origin https://github.com/HanleyLee/Lang.git
- 修改为
ssh
:git remote set-url origin git@github.com:HanleyLee/Lang.git
快捷功能
- 快捷键查看所有快捷键: 使用
shift + ?
在所有 GitHub 页面上都可以查看快捷键 - 在评论中应用表情: 在评论中使用
:
便会启动表情自动补全功能
提交信息操作 issue
我们可以在 commit 信息中添加以下格式的文本, 然后相对应的 issue 便会有相对应的操作
- 仅指向 issue
#24
- 删除对应 issue
fix #24
fixes #24
fixed #24
close #24
closes #24
closed #24
resolve #24
resolves #24
resolved #24
参考
本博客文章采用 CC 4.0 协议,转载需注明出处和作者。