Git学习笔记整理

  • 2022-06-24 上午 / itsuki0927 /
  • 0人浏览 • 0条评论 • 0人喜欢
Git
article-header-cover
零零碎碎的学了一下 git , 也做了一些笔记, 之前的笔记比较零散, 所以这次有时间整理一下就出现了这篇文章, 这篇文章 = 文档 + 疑问.

保存 Add

  • git add <fileName> 将某一个文件添加到暂存区

  • git add . 将所有文件添加到暂存区

比较 diff

  • git diff 比较工作区与暂存区的差异

  • git diff --cached 比较暂存区与仓库的差异

提交 commit

  • git commit -m xxxx 提交更新

  • git commit -a -m xxxx 跳过使用暂存区域对已跟踪的文件提交更新

  • git commit -am xxxx 跳过使用暂存区域对已跟踪的文件提交更新

储藏 Stash

保存当前工作进度,会把暂存区和工作区的改动保存起来

  • git stashgit stash push 推送 stash 到 stash 栈

  • git stash -u/--include-untracked 贮藏已修改、暂存的已跟踪文件和未跟踪文件

  • git stash push -m <message> 添加到 stash 栈,并加一个 message

  • git stash list 查看 stash 栈

  • git stash apply 应用最上层 stash

  • git stash apply <stashName> 应用指定 stash

  • git stash apply --index

  • git stash pop 移除栈顶 stash

  • git stash drop <stashName> 移除指定 stash

  • git stash clear 清空 stash 栈

  • git stash branch <branchName> 用 stash 的修改创建一个新的分支,创建成功后删除此 stash

  • git stash branch <branchName> <stashName> 指定 stashName 的修改创建一个新的分支,创建成功后删除此 stash

状态 Status

  • git status 检查状态

标签 Tag

Git 支持两种标签: 轻量标签与附注标签

轻量标签

像一个不会改变的分支 – 它只是某个特定提交的引用

附注标签

存储在 Git 数据库中的一个完整对象,它们是可以被校验的.

命令

  • git tag 列出已有标签

  • git tag -ln 查看标签详细信息

  • git tag <tagName> 创建轻量标签

  • git tag -a(可省略) <tagName> -m <message> 创建附注标签

  • git tag -a <tagName> <hashCode> 给指定 commit 打标签

  • git show <tagName> 查看指定标签

  • git push <remoteName> --tags 将全部标签推送到远程仓库

  • git push <remoteName> --delete <tagName> 删除远程标签

  • git tag -d <tagName> 删除指定标签

  • git checkout <tagName> 检出标签 没懂

  • git push <remoteName> <tagName> 将指定标签推送到远程仓库

责怪 Blame

  • git blame <fileName> fileName 进行 blame

  • git blame -L start,end <fileName> fileName 进行 blame 限制 start,end 行

  • git blame -e <fileName> -e 显示邮箱

  • git blame -w <fileName> -w 忽略空格修改

  • git blame -M <fileName> -M 选项检测同一文件中移动或复制的行。这将报告行的原始作者,而不是移动或复制行的最后一个作者。

  • git blame -C <fileName> -C 选项检测从其他文件中移动或复制的行。这将报告行的原始作者,而不是移动或复制行的最后一个作者。

检出 Checkout

  • git checkout .git checkout <filename> 将暂存区文件替换工作区文件。

  • git checkout <commitId> 检出

  • git checkout HEAD .git checkout HEAD <file> 将 HEAD 指向的版本库文件同时替换暂存区和工作区文件。

  • git checkout -- <fileName> 将 fileName 恢复到最近一次 add/commit(–的作用就是:区分有同名的分支)

清除 clean

git checkoutgit reset命令对之前添加到 Git 跟踪索引的文件进行操作, 而git clean命令对未跟踪的文件进行操作。

  • git clean -n 提醒哪些文件会被删除

  • git clean -dn 提醒哪些文件/文件夹会被删除

  • git clean -f 删除当前目录下所有没被追踪的文件

  • git clean -df 删除当前目录下所有没被追踪的文件/文件夹

  • git clean -f <path> 删除指定目录下所有没被追踪的文件

  • git clean -x 删除所有没被最终的文件(包括.gitignore 忽略的文件)

  • git clean -di 交互式会话删除

反转 Revert

在当前提交后面, 新增一次提交, 抵消掉上一次提交导致的所有变化(适合于 push 到远程分支, 然后需要抵消掉某一次的 commit).

  • git revert HEAD revert 上次 commit

  • git revert <commitId> revert 指定 commitId commit

  • git revert --no-edit HEAD 不会出现编辑 commit message

  • git revert -n/--no-commit HEAD 不会自动 commit

重回 Reset

  • git reset --hard <commitId> 回退版本(更新工作区、暂存区、仓库)

  • git reset --mixed <commitId> 回退版本(默认选项,更新暂存区、工作区)

  • git reset --soft <commitId> 回退版本(更新仓库)

  • git reset --hard HEAD^ 回退到上一个版本

  • git reset --hard HEAD^<number> 回退 number 个版本

  • git reset <commitId> <fileName> 回退 fileName 到指定版本

移除 Rm

git 索引中删除被跟踪的文件

  • git rm <fileName> 删除文件(需要在暂存区,会删除文件)

  • git rm --force/-f <fileName> 移除之前修改过/已经放到暂存区的文件(会删除文件)

  • git rm --cached <fileName> 移除暂存区文件(保存在磁盘,并不想让 Git 继续跟踪)

  • git rm -r dirName 删除文件夹(需要在暂存区)

Commit –amend

修改最新提交的便捷方法,它可以将分阶段的更改与先前的提交结合在一起,而无需创建全新的提交。

  • git commit --amend 重新提交(漏掉了几个文件没有添加,或者提交信息写错了,第二次提交将替换第一次提交的结果)

  • git commit --amend -m <message> 快捷方式

  • git commit --amend --no-edit 允许您在不更改提交消息的情况下对提交进行修改

Rebase

变基: 当前执行 rebase 分支的所有基于原分支提交点之后的 commit 打散成一个个的 patch,
并重新生成一个新的 commit hash 值,再次基于原分支目前的最新 commit 点上进行提交,
并不根据两个分支上实际的每次提交的时间点排序,rebase 完成后,
切到基分支进行合并到另一个时也不会生成一个新的 commit 点,可以保持整个 Git 状态树的完美线性

rebaseImage

原理: 首先找到这两个分支(当前分支experiment,变基操作的目标基底分支master)的最近共同祖先C2,
然后对比当前分支相对于该祖先的历次提交,提交相对应的修改并存为临时文件,然后将当然分支执行目标基底C3,
最后以此将之前另存为临时文件的修改依序应用.

简而言之: 这里就是提取C4中引入的补丁和修改,然后在C3的基础上应用一次.

git rebase -r/--rebase-merges <branchName> 让 commit 保持原样,不会修改提交信息,仍然是分支历史记录中的单个提交。

Rebase -i

交互式 rebase

// Commands:
//  p, pick <commit> = 提交commit
//  r, reword <commit> = 提交commit,edit提交信息
//  e, edit <commit> = use commit, but stop for amending
//  s, squash <commit> = 与上一个commit合并成一个commit,并且edit提交信息
//  f, fixup <commit> = 与上一个commit合并成一个commit,使用上一个commit提交信息来展示
//  x, exec <command> = run command (the rest of the line) using shell
//  b, break = 卡在这里 (继续则需要使用'git rebase --continue' // NOTE: 没用)
//  d, drop <commit> = 删除这次commit
//  l, label <label> = label current HEAD with a name
//  t, reset <label> = reset HEAD to a label
//  m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]

Reflog

每次更新了 HEAD 的 git 命令比如 commint、amend、cherry-pick、reset、revert 等都会被记录下来(不限分支),
就像 shell 的 history 一样。 这样你可以 reset 到任何一次更新了 HEAD 的操作之后,
而不仅仅是回到当前分支下的某个 commit 之后的状态。

远程 Remote

  • git remote -v 显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URL

  • git remote add <remoteName> <url> 添加远程仓库

  • git remote show <remote> 查看某个远程仓库

  • git remote rename <oldRemoteName> <newRemoteName> 远程仓库重命名

  • git remote remove <remoteName> 远程仓库移除

  • git fetch <remote> 访问远程仓库,从中拉取所有你还没有的数据

  • git push <remoteName> <branchName> 推送到远程分支

填充 Fetch

将远程分支最新内容拉取到本地,但是 fetch 之后是看不到内容的,此时会多出一个FETCH_HEAD分支,
这个分支就保存着 FETCH 后的内容

  • git fetch <remoteName> <branchName> 填充数据

推送 Push

  • git push <remoteName> <branchName> 将分支推送到远程

  • git push <remoteName> <tagName> 将标签推送到远程

  • git push <remoteName> --all 将所有分支推送到远程

  • git push <remoteName> --tags 将所有标签推送到远程

  • git push -f 强制推送远程(一般如果使用了git commit --amendgit rebase都会出现此情况)

拉取 Pull

首先运行 git fetch,它从指定的远程存储库下载内容.然后执行git merge
将远程内容引用合并到新的本地合并提交中

  • git pull <remoteName> <branchName> 将远程分支拉取下来并与本地分支合并

  • git pull --rebase <remoteName> <branchName> 将远程分支拉取下来并与本地分支变基

  • git pull --no-commit <remoteName> 与默认效果相似,但是不会创建一个 commit 记录

分支 Branch

merge: 合并分支会让两个分支的每一次提交都按照提交时间排序,并且会将两个分支的最新一次 commit 点进行合并成一个新的 commit,
最终的分支树呈现非整条线性直线的形式

  • git branch <branchName> 创建分支

  • git branch 列出所有分支(–merged 已经合并分支/–no-merged 未合并分支)

  • git branch -d <branchName> 删除指定分支

  • git checkout -b <branchName> 创建并切换到该分支(git 2.27 以前)

  • git switch -c <branchName> 创建并切换到该分支(git 2.27 以后)

  • git checkout <branchName> 切换到指定分支

  • git merge <branchName> 合并到当前分支

重命名操作 mv

  • git mv oldFileName newFileName 重命名文件

查看操作 log

  • git log 查看版本
  • git log -p -number 查看(每次/-number)提交所引入的差异
  • git log --stat 查看每次提交的简略信息

一些问题

快进(fast-forward)

试图合并两个分支时,如果顺着一个分支走下去能够到达另一个分支,那么 Git 在合并两者的时候,只会简单的将指针向前推进(指针右移),
因为这种情况下的合并操作没有需要解决的分歧–这就叫做”快进”

三棵树 Three trees

工作区

写代码的文件目录

暂存区

相当于一个存档

git add: 工作区的变更内容 -> 暂存区

仓库

存放数据的地方,HEAD 指向当前版本

git commit: 暂存区的变更内容 -> 仓库

reset 和 checkout 的区别

  1. reset 是移动 HEAD 指向的分支
  2. checkout 是移动 HEAD

originalImg

checkout

checkoutImg

reset

resetImg

git checkout filename

命令 git checkout readme.txt 意思就是,把 readme.txt 文件在工作区的修改全部撤销,这里有两种情况:

  • 一种是 readme.txt 自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;

  • 一种是 readme.txt 已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。

总之,就是让这个文件回到最近一次 git commitgit add 时的状态。

rm / git rm 删除之后怎么恢复

使用 rm 删除文件

这个删除恢复的前提是在你把文件添加到暂存区里了,想要恢复可以使用git checkout -- <fileName>

使用 git rm 删除文件

如果用 git rm 删除文件,就相当于不仅删除了文件,而且还添加到了暂存区,需要先使用git reset HEAD <fileName>,
然后在使用git checkout -- <fileName>就可以恢复了

重命名文件的两种方式

第一种

  1. mv a.txt b.txt 先使用 mv 命令将 a 文件重命名 b 文件
  2. git add b.txt 使用 git add 将 b 文件添加到暂存区
  3. git rm a.txt 使用 git rm 将 a 文件从暂存区删除

第二种

  1. git mv a.txt b.txt 直接使用git mv old-file-name new-file-name 进行重命名

如果是从Index重命名成index的时候, 个人推荐使用第二种, 因为假如是 mac 电脑是不区分大小的, 但是 linux 系统是区分的, 所以你在本地改了, push 上去远程还是没有改.

pull 和 fetch 的区别

  1. fetch 等同于拉取最新的代码到一个FETCH_HEAD
  2. pull = fetch + merge FETCH_HEAD
  3. pull –rebase = fetch + rebase FETCH_HEAD
  4. fetch 是安全的命令,因为git fetch将下载远程内容,并且不会改变本地存储库的状态
  5. pull 是不安全的命令,因为git pull将下载远程内容,并立即尝试更改本地状态以匹配该内容,
    可能会导致本地存储仓库处于冲突状态。
最后更新: 2022-08-06 上午
永久地址: https://itsuki.cn/article/176
上一篇

一个专升本的五年自救记录

下一篇

从网易到字节,专升本的校招经验分享