1. git 中的 HEAD 是一个指针,指向当前所在的版本。
HEAD^ : 指当前版本的前一个版本。
HEAD^^ : 指当前版本的前前一个版本,以此类推。
HEAD~3 :以当前版本为基准,回退3个版本。
2. 修改提交流程介绍
工作区修改 add--> 暂存区 commit--> 本地仓库 push--> 远程仓库。
.git
,这个不算工作区,而是Git的版本库。Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master
,以及指向master
的一个指针叫HEAD
。3. 远程仓库的默认名称是origin。
分支名前带 origin/,是远程分支。
git init // 初始化一个版本仓库。如果想把本地的某个文件夹作为本地仓库,就在该文件夹执行这个操作。作为git clone之前的第一个操作
git --version // 查看 git 版本
git pull // 拉取远程代码
git pull -h | grep depth // 只拉取master分支的提交记录(未验证)
git status // 仓库当前状态
git rm 文件 // 删除
git remote // 查看远程信息
git remote -v // 查看远程仓库的 url
git remote add origin https://github.com/xxxx/xxx.git // 关联本地库和远程库
git remote set-url origin https://github.com/xxxx/xxx.git // 更改远程仓库地址
git clone http://xxx.git // 克隆项目到本地,项目名跟远程的一样
git clone http://xxx.git my-project // 克隆项目到本地并命名为 my-project 项目
git clone -b dev http://xxx.git // 克隆项目到本地,只克隆 dev 分支
git clone --depth=1 http://xxx.git // 克隆项目到本地,只克隆最近一次commit
git clone --depth=1 --single-branch --branch master https://xxx.git // 克隆项目到本地,只包含 master 分支的最近一次 commit
git checkout -- // 撤销某个文件在工作区的更改
git checkout . // 撤销全部文件在工作区的更改
1. git stash save "save message":贮藏工作区和暂存区的内容(新添加的 stash 会放在 stash list 的第一个位置)。
贮藏的内容是全局的,各个分支都可以使用 stash list 中的内容。
如果你不想保存时做备注,直接 git stash 也可以。
注意:新添加的文件不能被贮藏。
2. git stash list : 查看贮藏列表。
3. git stash apply: 使用贮藏列表里的第一个内容。
git stash apply stash@{2} --index : 使用指定贮藏的内容,stash内容并不删除,你需要用git stash drop来删除。
--index 参数使用时使本来在暂存区的内容还是在暂存区,不加参数暂存区的内容会回到工作区。
4. git stash pop:弹出贮藏列表里的第一个内容,随后删除该记录。
git stash pop stash@{1} --index
5. git stash branch
6. git stash drop stash@{3}:从 stash list 中移除指定贮藏。
7. git stash clear:清空所有贮藏
1. git add
git add . :添加所有文件到暂存区。
1. git commit
git commit -m "commit file“: 提交所有暂存文件到本地仓库并注释。
2. git commit --amend -m 'xxx' :向最后一次提交追加文件并修改最后一次提交信息。
git commit --amend :向最后一次提交追加文件。
注意:只要你的分支没有合并到过别的分支,怎么 amend 都没有问题。如果你的分支已经合到过别的分支,然后你又在你的分支最后一个提交里 amend 内容了,有些场景会出现问题。比如,刚开始我写了一片代码,然后把分支合到别的分支,我又切回自己的分支,把之前写的代码删了,打算放在另外的地方,然后把这次修改 amend 到我的分支的最后一次提交,然后再把我的分支再合到之前合过一次的分支,发现有2个地方出现了重复的代码,第一次写的那些代码没有被删除,还是在原来的地方。
原因:你删了之前那些代码在别的地方重新写了一遍然后 amend 以后,你可以在 sourceTree 看一下最后一次提交的更改内容,没有删除操作,只有重新写的操作,所以再把自己的分支合并过去的时候之前写的内容不会去动它,然后又新加了重新写的代码,这样就出现了问题。
解决:提交已经合并到过别的分支以后,最好别在那个分支上 amend 了,新的修改最好新追加个提交。
reset 操作是无痕的,不会产生提交记录,也不影响后续提交再次合入,reset 节点之后的提交记录会被删除。
暂存区回退:
git reset HEAD
git reset HEAD . :把暂存区的所有文件回退到工作区。
本地提交回退:
1. git reset --soft HEAD^ : 恢复最近一次提交
2. git reset --soft commitId : 重置到某次提交。
reset 提交有3种模式:
本地分支 reset 完以后会落后远程分支,可以用 git push -f 强制推送到远程仓库使远程分支跟本地分支保持同步。
reset 操作只影响当前操作的分支,不会影响到别的分支。当把 reset 过的分支跟别的分支合并时,不会因为 commit 被 reset 掉了而把另外一个分支的 commit 也去掉了。比如,从 a 分支切出一个 b 分支,再把 b 分支中的 commit1 reset 掉,然后把 b 分支合到 a 分支,合并完以后 a 分支上的 commit1 还是会存在的,不会因为在 b 分支上被 reset 掉了而受影响。
使用 git reset 时,reset 掉的 commit 在 Source Tree 的分支图上是按照层级顺序来的,而不是简单的看提交时间的先后顺序(这里要特别注意)
git revert 其实就是把那次提交的代码反向修改回去,被回滚的提交记录会被保留,revert 会产生一个新的提交记录。
1. git revert HEAD : 回滚最近一次提交。
2. git revert commitId : 撤销指定的提交。
3. revert 合并提交
用上面的方法 revert 合并提交是会报错的,因为合并提交是两条分支的交集节点,而 git 不知道需要撤销的哪一条分支上的代码,需要添加参数 -m 指定主线分支(从1开始),保留主线分支的代码,另一条则被撤销。一般使用 1 保留主分支代码:git revert -m 1 commitId。
revert 一次合并提交时,被撤销掉的代码包括:
4. 再次合并 revert 掉的 commit 是合不进来的,会提示【Already up to date.】,因为分支上已经有那次commit的提交记录了,只要再 revert 一次之前的 revertId 就行了(负负得正):git revert [之前revert操作的commitId]
1. git merge --no-ff origin/dev -m 'merge dev branch':合并远程dev分支到当前分支
合并分支时,Git 可能会用 Fast forward
模式,但这种模式下,删除分支后,会丢掉分支信息。可以用 --no-ff 参数强制禁用Fast forward
模式,使用普通模式合并,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
2. git merge --abort:中止合并
1. git cherry-pick commitId:挑选单个提交合并到当前分支。
注意:用 cherry-pick 合并过来的提交会产生一个新的 commitId,但是日期保持不变。用 cherry-pick 合并的提交会多一个“提交日期”,sourceTree commit 列表的日期显示的就是提交日期,提交日期就是用 cherry-pick 合代码的日期,git log 显示的日期不是提交日期。
2个分支差异对比时,用 cherry-pick 合并的提交还是会显示在分支差异里面,但是代码其实已经是存在当前分支了。
2. git cherry-pick commitId1 commitId2 commitId3: 一次合并多个提交,合并过来的顺序是 commitId1 commitId2 commitId3。
一次合并多个提交,git 会依次检查合并过来的提交跟当前分支有没有冲突,有冲突的话要依次解决并提交。比如 commitId1 合进来有冲突,git 会先暂停后面提交的合入,我们要先解决 commitId1 的冲突,冲突解决完提交。提交完后可以 git status 查看一下 git 状态,应该会有 git cherry-pick --continue 的提示,然后执行 git cherry-pick --continue 继续后面提交的合并,如果又出现冲突,重复 commitId1 的操作,直到你执行 git cherry-pick --continue 出现以下提示:
这时,说明你要合并的提交都已经全部合并完了。
3. git cherry-pick commitId1..commitId3: 合并 commitId1 到 commitId3 之间的提交(不包括commitId1)
注意:提交 commitId1 必须早于提交 commitId3,否则命令将失败,但不会报错。
4. git cherry-pick commitId1^..commitId3: 合并 commitId1 到 commitId3 之间的提交(包括commitId1)
5. git cherry-pick --abort: 中止整个 cherry-pick 操作(回到操作前的样子,就像什么都没发生过)。
6. git cherry-pick --quit : 不回到操作前的样子。即保留已经 cherry-pick 成功的 commit,并退出 cherry-pick 流程。
cherry-pick 常用配置项:
(1)-n,--no-commit
只更新工作区和暂存区,不产生新的提交。
(2)-x
在提交信息的末尾追加一行(cherry picked from commit ...),方便以后查到这个提交是如何产生的。
(3)-m parent-number,--mainline parent-number
如果原始提交是一个合并节点,来自于两个分支的合并,那么 Cherry pick 默认将失败,因为它不知道应该采用哪个分支的代码变动。
-m配置项告诉 Git,应该采用哪个分支的变动。它的参数parent-number是一个从1开始的整数,代表原始提交的父分支编号。
$ git cherry-pick -m 1
上面命令表示,Cherry pick 采用提交commitHash来自编号1的父分支的变动。
一般来说,1号父分支是接受变动的分支,2号父分支是作为变动来源的分支。
1. git branch:显示所有本地分支。
2. git branch -r:显示所有远程分支。
3. git branch -a:显示所有分支(包括本地分支和远程分支)。
4. git branch dev:创建本地dev分支。
5. git checkout -b 新分支名:以当前分支创建一个本地新分支。
git checkout -b [path]/[branchName]: 在 path 文件夹下创建新分支
git checkout -b 本地新分支名 origin/远程分支名:以远程某个分支创建本地新分支(如果是新创建的远程分支,需要先 "git pull" 或 “git fetch origin 新建的远程分支” 一下)
git checkout -b 本地新分支名 commit_id: 基于指定提交创建本地新分支
6. git fetch origin 新建的远程分支:拉取远程分支到本地
7. git branch -d dev:删除dev分支。
git branch -d dev1 dev2 : 删除多个分支(dev1 dev2)
8. git branch -D dev:强行删除dev分支。
9. git branch -d -r origin/dev: 删除远程 origin/dev 分支
git push origin :dev 删除远程的dev分支。
10. git branch --set-upstream-to=origin/remote_branch your_branch:origin/remote_branch 本地分支对应的远程分支;your_branch当前的本地分支。
11. git checkout dev:切换到dev分支。
12. git checkout dev~3:切换到dev分支,并向前移动3次提交。这会造成HEAD分离,在为分离的HEAD添加新的提交的时候应该创建一个新的分支。
13. git checkout commit_id:切换到某次提交
14. git checkout tag_name: 切换到指定tag
14. git branch -M mian:修改本地当前分支名为mian。如果本地分支main已存在,要加 -M 强制修改,-m 不是强制修改。
git branch -M oldbranch newbranch:分支重命名 --修改本地的 oldbranch 分支名为 newbranch
15. git log branch1 ^branch2: 查看branch1分支有,而branch2中没有的 commit(在 GitLab 上相当于 Compare 的功能,Compare 是显示 to 分支上有而 from 分支上没有的 commit)。
16. git branch --merged master: 列出已经合并到master中的分支
git branch --merged:列出合并到HEAD中的分支(即当前分支的尖端)
git branch --no-merged master: 列出尚未合并到master的分支。默认情况下,这仅适用于本地分支。该-a标志将显示本地和远程分支,并且-r标志仅显示远程分支。
1. git push:把本地仓库的提交推送到关联的远程仓库
git push -u origin master
:推送当前分支到远程的 master(远程没有master分支的话会新建),并会建立本地分支和远程分支的关联关系。-u 全称 --set-upstream
git push origin local_branch:remote_branch:把本地local_branch分支推送到远程(远程没有remote_branch分支,会新建remote_branch分支)
1. git worktree:多个分支一起开发时,只要是提交的内容分支之间都能同步详情。(v2.6.0)
1. git log:查看日志。
2. git reflog: 显示 commit 操作记录(常用于错误操作后找回记录)。
3. git reflog show
3. git log --pretty=oneline 简洁日志版本号
4. git log --pretty=oneline 文件路径,获取该文件的提交记录
git show commit_id 文件路径:显示某个文件在某次提交中的更改
5. git log --graph --pretty=oneline --abbrev-commit 查看分支合并情况
6. git log --graph 查看分支合并图
1. git tag: 查看本地标签
2. git tag v1.0.0: 给当前分支打上标签
3. git tag v1.0.0 commitId: 给某次提交打上标签
4. git tag -a v1.0.0 -m 'version 1.0.0' commitId:给某次提交打上标签并附有注释
5. git tag -d v1.0.0: 删除本地标签
6. git push origin :refs/tags/v1.0.0: 删除远程标签
7. git push origin v1.0.0: 推送某个标签到远端
8. git push origin --tags: 一次性推送全部尚未推送到远程的本地标签
9. git show v1.0.0:查看标签信息
10. git tag --list:查看标签列表
git 配置文件保存在三个不同的位置:
每一个级别会覆盖上一级别的配置,所以 .git/config 的配置变量会覆盖 /etc/gitconfig 中的配置变量。
git 项目用户名和邮箱设置
git config user.name "用户名"
git config user.email "邮箱"
修改当前项目 git 的用户名、邮箱。
如果要查看全局的 git 用户名、邮箱,只需要加 --global 选项,例如:
git config --global user.name:查看
git config --global user.name "用户名":修改
这个用户名是多人开发提交代码时显示的名字,如果要提交到的 GitHub 账号和本地配置的 Git 邮箱一致,将会认为是自己给自己的账号提交,那么本地配置的用户名将不起作用,直接会使用 GitHub 账号里的名字。
git会根据用户的名字和邮箱来记录提交。GitHub也是用这些信息来做权限的处理。
在 Source Tree 上选择“按层级顺序”查看 Git 图表时,你会发现合并进来的分支的 commit 都是在当前分支的上面的,不管 commit 的时间是前是后。