Git-cli 文章教程知识点

发布于 2024-08-12 05:18:43 字数 27200 浏览 15 评论 0

git 追踪的只是修改,不是文件,只有将修改 add 到 stage 之后的内容才会被管理。

Git 相关图片

git-cli 相关书籍资料

配置

核心配置

  • 生成公钥私钥: ssh-keygen -t rsa -C "youremail@example.com" 在.ssh 文件夹中会生成 id_rsa 和 id_rsa.pub 两个文件,其中 id_rsa.pub 是公钥,可以提供给别人,id_rsa 是私钥,要保持仅自己知道
  • 初始化配置:
    • 配置用户名: git config --global user.name "xxx"
    • 配置邮箱: git config --global user.email "xxx@gmail.com"
  • 关闭追踪文件权限: git config --global core.fileMode false
  • 启动大小写敏感: git config core.ignorecase false
  • 显示中文文件名: git config --global core.quotepath false
  • 默认的编译器: git config --global core.editor vim
  • 保证 window 和*unix 中的换行符一致: git config --global core.safecrlf true
  • 设置 git push 的默认方式,对 git 2.X Git warning: push.default is unset; its implicit value is changing : git config –global push.default simple
  • 配置 github 使用 git 命令访问慢的情况: git config --global http. https://github.com.proxy socks5://127.0.0.1:1086; git config --global https. https://github.com.proxy socks5://127.0.0.1:1086 ,详见[这里][]

提高效率

  • log 更全更好看: git config --global alias.lg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative"
  • reflog 个性化输出: git config --global alias.rlg "reflog --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative"
  • 开启给 git 输出着色: git config --global color.ui true
  • git config credential.helper store : 保存需要输入账户密码的链接,例如以 https 的方式链接的,设置了 credential.helper store 之后只要再输入一次账户密码就会记住了
  • windows 中文乱码解决办法: 中文乱码
  • 访问 github 更加快: git config --global https.proxy 'socks5://127.0.0.1:<PORT>'

config

  • 查看全部配置: git config --list

init

  • git init : 新建一个 git 版本管理库
  • git --bare init : 新建一个 git 版本管理库裸库,用于提交 commit

clone

将远程库中的代码 clone 到本地,支持 HTTPS 协议和 SSH 协议,建议使用 ssh 协议,除了传输更快之外,ssh 协议还能保存用户账户密码信息,下次 pull push 可以不用输入

checkout

切换分支;撤销修改

  • git checkout <BRANCH> : 切换到 BRANCH 分支
  • git checkout -- <FIELNAME> : 撤销 FILENAM 的修改,( -- 很重要,如果没有就会变成切换分支),这里撤销修改有两个情况
    • FIELNAME 已经添加到暂存区(stage) 后,又作了修改,撤销修改就回到添加到暂存区(stage) 后的状态
    • FIELNAME 一直没有被放到暂存区(stage),撤销修改就回到和版本库状态
  • 撤销修改:
    • git checkout -- . : 撤销当前目录的修改
    • git checkout -- /specific/path : 撤销指定目录的修改

fetch pull

  • Git fetch 和 git pull 区别 : fetch 只拉取远程 commit 数据,改变了 remote 里面的 commit id,不会自动合并;pull 拉取最新 commit 并将其 merge,简单的讲 git pull = git fetch + git merge
  • fork 项目开发,同步代码 git fetch upstream; git <merge|rebase> upstream/master; git push origin/master : Git fork 项目后,上游项目更新了 同时更新自己的项目
  • 将 origin/upstream 的 PR 远端拉到本地 review: git fetch origin/upstream pull/ID/head:BRANCHNAME

branch

  • 列出分支: 本地分支 git branch 及全部 git branch -a
  • 查看分支及对应的远程分支: git branch -vgit branch -vvFind out which remote branch a local branch is tracking
  • 新建分支:
    • 新建分支: git branch <new_branch> <src_branch> 从 src_branch 创建一个新的分支 new_branch
    • 新建分支同时切换分支: git checkout -b <new_branch> <src_branch>
  • 删除分支:
    • 删除本地分支: git branch -d <branch>
    • 强行删除没有合并的分支: git branch -D <branch>
    • 删除远程分支: git push oririn :<branch> 或者 git push --delete origin <brancbranchhName> 推荐使用后者( --delete 可改成 -d )
    • 如果一个分支合并到 master 后,正确的删除方式是:
      • 远程分支仍存在: git push origin --delete <branch> 然后 git branch -D <branch>
      • 远程分支合并后在 github/gitlab 的 PR 页面已经删除: git fetch origin -p 然后 git branch -D <branch>
    • 删除本地的 remote/<origin|upstream>/branch 分支 git 命令行删除远程分支
      • 如果远程服务器已经没有该分支: git fetch -p 或者 git pull -p
      • 如果远程服务器还有该分支,想在删除 track 的分支: git branch --delete --remoets <remote|upstream>/<branch> ,或者缩写 git branch -dr <remote>/<branch>
  • 远程分支已删除但是本地还有 remote/[origin|upstream]/<branch> 暂存在本地的远程分支, 类似这个 : git pull -p 或者 git fetch -p , -pprune 的缩写,所以也可以直接使用 git pull/fetch prune

add

将工作区(working tree) 中的文件加入到缓存区(staged index)

  • git add <FILENAME> : 指定 FILENAME 文件加入 staged index
  • git add . : 将 working tree 所有的文件加入 staged index
  • git add -f <FILENAME> : 将 .gitignore 中忽略的 FILENAME 文件强行加入 staged index

commit

  • 允许提交 commit 信息为空 Git commit with no commit message :
    • 仅这次提交为空 git commit -a --allow-empty-message -m ''
    • 设置全局别名 git config --global alias.nmcommit 'commit -a --allow-empty-message -m ""'
  • 修改上次提交的内容
    • 修改上一次提交的作者信息 Change commit author at one specific commit : git commit --amend --author="Author Name <email@address.com>"
    • 增加文件到上一个 commit: git add [file]; git commit --amend --no-edit 增加 --no-edit 表示不修改上一次提交的 commit 信息

merge

用于合并分支,如果合并后出现冲突,会以 <<<<<<< ======= >>>>>>> 标记框出来

  • git merge <BRANCH> : 将 BRANCH 分支合并到当前分支
  • git merge --ff-only <BRANCH> : 将 BRANCH 分支仅以 fast-forward 的方式合并到当前分支
  • git merge --allow-unrelated-histories <BRANCH> : 允许将两个没有相关历史的分支进行合并
  • --squash 的使用
    • git checkout master : 切换到 master
    • git merge --squash bugfix : merge 带上 squash 标识符,会将多个 commit 合并成一个 commit
    • git commit : 因为合并成一个 commit,所以要重新 commit 一下,此时的 commit 信息是可编辑的
  • 合并遇到冲突时使用他们的分支内容, 详见这里 : git merge --strategy-option theirs

rebase

  • git rebase <master|upstream/master> : 当前的 bug 或者 featrue 分支完成开发,rebase 到 master|upstream/master 做好向远端提交的准备
  • git rebase -i HEAD^ : 发现上一个提交错了,或者 review 了代码后需要修改,可以 rebase 上一个 commit,会保留之前的修改和 commite message.完成后使用 git add.; git rebase --continue .但是部分社区不喜欢 rebase,喜欢根据 review 新建一个 commit 或者 revert 提交到对 branch,从而避免重复 review
  • git rebase -i sha-1 modify pick to edit git rebase --continue : How to modify a specified commit in git
  • git rebase --abort : 放弃当前的 rebase
  • git rebase --skip : rebase 多步解决冲突的过程中,conflict 发现和上一个 rebase 内容一样(即完全舍弃了来自 conflict 分支的内容),这时使用 git rebase --skip 进去下一步
  • git rebase -i --root : Change first commit of project with Git? [duplicate]

remote

  • 查看 remote: git remote , git remote -v
  • 增加远程仓库: git remote add origin git@server-name:path/repo-name.git origin 为默认远程仓库名,可以自定义,多个远程仓库类似 github 上 fork 了原仓库同时要追踪原仓库的变化时,可以增加一个 upstream 分支,定期更新该分支并合并 origin 对应的分支, github Collaborating - Configuring a remote for a fork
  • 删除 remote: git remote remove <your_remote_name>
  • 修改 remote 名称: git remote rename <old> <new>
  • 修改分支对应的地址 How to change remote origin from Git : git remote set-url origin git://<new.url.here>
  • 同步 upstream 内容到 origin github Collaborating - Syncing a fork 用于 fork 开源项目并对其进行二次开发的同步更新
    • 从 upstream 中更新: git fetch upstream
    • 将 master rebase 在 upstream/master 上: git checkout master; git rebase upstream/master
    • merge to master: git checkout master; git merge upstream/master ,这个操作会将 fork/master 内容同步成 upstream/master 的情况, 且会将本地的提交放到最 git log 的最前

log

  • Git 基础 - 查看提交历史 :
    • git log : 简单的查看日志命令
    • git show sha-1 : 查看指定哈希值的日志
    • git log -n 3 : 查看近三条日志记录,可以是本地的,可以是远程的
    • git log -p -2 <filename> : 查看某个文件(可选) 的近两次提交
    • git log --stat : 查看日志同时查看每个 commit 修改了什么内容和改变了多少行
    • git log --graph --oneline --abbrev-commit : 查看 git 日志,每个 commit 一行,且显示图, --abbrev-commit 显示简短 commit 哈希值
  • 个性化你的 Git Log 的输出格式 git log --pretty=format:"%h %ci %cn %ce %s" 参数分别是: 哈希 日期 名称 邮箱 概述
  • git shortlog -nes : 查看短 log 参数为: 短 log name + email + summary

reflog

reflog 是数据回复工具,在使用 Git 的过程中,有时会不小心丢失 commit 信息,这时可以使用 reflog 进行数据恢复

  • git reflog
  • git reflog --format='%C(auto)%h %<|(17)%gd %C(blue)%ci%C(reset) %s <%an %ae>' 格式化 reflog 的输出

push

将本地的分支更新的内容和远程分支关联起来,一般适用于需要多人合作的时候

  • git push --set-upstream origin <your_branch_name> 或者简写成 git -u origin master (推荐): 创建远程分支,将当前分支代码提交到远程分支,并将本地的 branch 关联到 remote
  • git push -f origin : 强力提交代码,会覆盖掉远程代码,例如 git 回滚到任意版本 git reset -hard <commit_id>; git push -f origin (仅作为例子,不推荐使用,更应该使用 revert )

diff

diff 显示两个版本之间的差异

git-diff

  • git diff [filename] : 比较工作目录(Working tree) 和暂存区(staged index) 文件的区别
  • git diff --cached [filename] : 比较暂存区(staged index) 和上次提交(HEAD) 快照的区别
  • git diff HEAD : 比较工作目录(Working tree) 和上次提交(HEAD)
  • git diff HEAD^ HEAD : 查看上次和上上次提交的差别
  • git diff origin/branch-1 [filename] : 比较 branch-1 本地分支和远端分支的区别
  • git diff <commit_hash1> <commit_hash2> : 比较同一分支上两个 commit 的 diff
  • git diff <commit_hash1> <commit_hash2> <filename> : 比较两个 commit 某个文件的差别
  • git diff --name-only <commit_hash1> <commit_hash2> : 仅显示两个 commit 不同文件的名称
  • git diff <branch1>..<branch2> : 比较两个分支上最新的提交的 diff
  • git diff --stat <COMMIT> <COMMIT> : diff 统计结果,显示每个文件增减的数量,最后显示这个 patch 的总增减量
  • 查看两个分支的不同:
  • git diff --no-index filename_1 filename_2 : 通过 git 比较 linux 文件的差异,不用两个文件在 git 的仓库中
  • git diff --check : 检查 git 中是否存在结尾的空格, How to not leave trailing whitespace (using your editor or Git) ,或者使用 git 的 pre-commit 钩子

stash

使用场景是:

  • 如果发现在上次提交中忘记了某些内容,并且已经开始在同一分支中处理下一个提交了
  • 在别的分支中工作时,接到非常紧急的需求需要快速完成

stash 将在工作目录(Working tree) 和暂存区(staged index) 的文件暂存起来.stash 的存储方式是 stack,所以最新的暂存信息会存储在最上面, stash@{<stash_num>} 的值越小

  • git stash : 当前分支所有没有 commit 的代码先暂存起来
  • git stash save <stash_name> : 将当前的修改暂存起来 并将暂存重命名为 <stash_name>
  • git stash list : 查看当前 branch 的 stash 记录
  • git stash apply stash@{N} : 恢复暂存了了 stash 信息
  • git stash drop : 删除上一条 stash
  • git stash drop stash@{N} : 删除指定的 git stash
  • git stash pop : 恢复并删除(不建议使用,这个操作不可逆,建议使用 git stash apply; git stash drop 代替)
  • git stash clear : 清空 stash
  • 在从 stash 恢复前查看 stash 里面和本地的不同 See what's in a stash without applying it : 显示最新 stash 内容的区别 git stash show -p 显示指定 stash 内容的区别 git stash show -p stash@{2} (这个建议在 ide 中进行查看方便对比和删除 stash)
  • git stash apply stash^{/<regex>} : find the stash by name using git's regular expression syntax by stash^{/<regex>} and apply stash How to name and retrieve a stash by name in git

reset

tag

tag 是将一个 git 的 commit 和标签关联,更容易记住的有意义的名字,能在检查和回退的时候更加便捷.Git 使用两种主要类型的标签:

  • 轻量标签 (lightweight): 轻量标签很像一个不会改变的分支 - 它只是一个特定提交的引用
  • 附注标签 (annotated): 附注标签是存储在 Git 数据库中的一个完整对象。它们是可以被校验的;其中包含打标签者的名字、电子邮件地址、日期时间;还有一个标签信息;并且可以使用 GNU Privacy Guard (GPG)签名与验证。 通常建议 创建附注标签,这样你可以拥有以上所有信息;但是如果你只是想用一个临时的标签,或者因为某些原因不想要保存那些信息,轻量标签也是可用的
  • 查看所有 tag: git tag
  • 为当前 commit 打上 tag: git tag v1.1
  • 为指定 commit(一般为过去的) 打上 tag: git tag v1.1 <commit_hash>
  • 打 tag 的同时为 tag 增加说明: git tag -a v1.1 -m "my tag message of tag 1.1"
  • 查看某个 tag 对应的 commit id: git show v1.1
  • 删除本地的 tag: git tag -d <tagName>
  • 删除远端的 tag: git push --delete origin <tagName>
  • 将本地其中的标签推动到远端: git push origin v1.1.0
  • 将本地所有的 tag 推送到远端: git push origin --tags
  • 删除类似的 tag,如 2.0.0-* 样式的 tag: git tag --list '2.0.0-*' | xargs -I % echo "git tag -d %; git push --delete origin %" | sh
  • checkout 到指定标签: 在 Git 中你并不能真的 checkout 指定的 tag,因为 checkout 只对 branch 有效,可以使用 git checkout -b <branchname> <tagname> 在指定标签上创建一个新分支然后进行 checkout

clean

清除某些内容

  • git clean -n : 查看有什么内容会删除但是不会进行实际的删除操作
  • git clean -fdx : 强行删除 untracked 的文件及文件夹,包括 ignore 的文件/文件夹
  • git clean -fdxi : 与上面类似但是进入交互性命令行进行删除
-q, --quiet              do not print names of files removed
-n, --dry-run            dry run
-f, --force              force
-i, --interactive        interactive cleaning
-d                       remove whole directories
-e, --exclude <pattern>  add <pattern> to ignore rules
-x                       remove ignored files, too
-X                       remove only ignored files

revert

生成一个新的 commit 来撤销某次 commit 的内容. revert 和 reset 的区别

  • git revert HEAD : 撤销上一次 commit
  • git revert HEAD^ : 撤销上上次 commit
  • git revert <commit_hash> : 撤销指定的 commit

cherry-pick

Apply the changes introduced by some existing commits

git cherry-pick [--edit] [-n] [-m parent-number] [-s] [-x] [--ff]
        [-S[<keyid>]] <commit>…​
git cherry-pick --continue
git cherry-pick --quit
git cherry-pick --abort
  • -x : 保留原来的 commit hash(仅仅在 commit 信息里面保存),可以使得 cherry-pick 之后的 hash 码保持和原来分支中的一样,对于开源项目来说很重要方便检查整体 cherry-pick 情况,对公共分支来说非常重要, 参考

rev-parse

Pick out and massage parameters

  • git rev-parse --short HEAD : 获取 HEAD 的短 hash 值
  • git rev-parse --abbrev-ref HEAD : 获取 HEAD 所属的分支名

rm

删除文件,会同时在本地文件系统和 git 中删除

  • git rm file : 不再追踪文件,并在文件系统删除文件,删除后还要提交 git commit
  • file1git rm --cached file : 不再追踪文件,但是不会在文件系统删除文件,之后 git commit

gitignore

.gitignore 可以忽略放在 git 目录里,但是不需要追踪和提交的文件

  • git check-ignore -v <file_name.ext> : 查看 gitignore 文件中那一行将 file_name.ext 过滤掉, 廖雪峰-git 忽略特殊文件 .想要将某个文件加入 stage index 但是一直失败,有可能是 gitignore 文件配置将其过滤了,导致文件不能被追踪
  • .gitignore 可以忽略自己本身改变,不用去编辑 .git/info/exclude 文件 .gitignore gitignore itself
  • A collection of useful .gitignore templates : github 中为常用的 gitignore 文件添加了模板
  • gitignore 的写法

     

    符号含义
    /目录 开头表示根目录
    *多个通配符
    ?单个通配符
    []单个字符匹配列表
    !不忽略追踪的文件或目录

ls-files

  • git ls-files -d | xargs echo -e | xargs git checkout -- : git 恢复所有 被删除 的文件
  • git ls-files -m | xargs echo -e | xargs git checkout -- : git 回复所有 被修改 的文件

update-index

git-update-index: Register file contents in the working tree to the index

根据 Do git update-index --assume-unchanged rules propagate to clients on pull 知道 update-index 仅对当前的本地库有效,因为 index 仅仅是存在本地中

  • git update-index [--skip-worktree | --assume-unchanged] <FILE_NAME> : 将文件保留在 git 中但是不追踪他的改变.因为在 gitignore 中的文件将不会在 git 中,如果要保持文件在 git 中,但是不追踪文件的改变可以使用 update-index .根据 Keep file in a Git repo, but don't track changes ,应该使用 --skip-worktree 更好,如果想要恢复改变可以使用 --no-skip-worktree/--no-assume-unchanged 。一般可以对配项目的配置文件进行设置,防止其被误操作提交到 git 中
  • git update-index --chmod=+x path/to/file : 修改文件 path/to/file 变成可执行文件, 想要将文件从可执行变成不可执行使用 git update-index --chmod=-x path/to/file

FAQ

git-cli 每次要求输入用户名密码

根据 这里

  • 使用 SSH 而非 HTTPS: 使用 https 会导致默认使用账户名密码, git remote -v 查看是否使用的协议,通过 git remote set-url origin git@github.com:username/repo.git 将 HTTPS 修改成 SSH
  • 配置凭证存储机制: git config --global credential.helper store 配置凭证存储,仅需下次再输入一次帐号密码就能记住密码

merge 和 rebase 的区别

  • merge : 合并两个 git 分支时,会按照 commit 的顺序排序进行合并
  • rebase : 会将当前分支的 commit 合并到 rebase 分支 HEAD 后面, git checkout patch; git rebase master 会将 master 和 patch 分支合并,且将仅在 patch 分支中有的 commit 合到 master 的 HEAD 后面

revert 和 reset 的区别

  • revert 是用一次新的 commit 来回滚之前的 commit,reset 是直接删除指定的 commit
  • reset 是把 HEAD 向后移动了一下,而 revert 是 HEAD 继续前进,新的 commit 的内容和要 revert 的内容正好相反,能够抵消要被 revert 的内容

github 或者 gitlab 合并 PR 过来的分支的时候

重命名追踪的文件

  • 一般直接修改文件名就能使得 git 追踪到重命名
  • 也可以通过 cli 进行修改,重命名 git 追踪的文件 git mv <folder|file> <folder|file> 如果是更改大小写但是平台是不区分大小写的话要引入中间变量 git mv src_file tmp; git mv tmp dest_fileIn a Git repository, how to properly rename a directory

怎么写好 commit message

获取当前的分支名

  • git branch | grep \* | cut -d ' ' -f2
  • git rev-parse --abbrev-ref HEAD

fork branch clone 的区别

so-区别

  • fork: 对存储仓库(repository)进行的远程的、服务器端的拷贝,从源头上就有所区别。复刻实际上不是 Git 的范畴。它更像是个政治/社会概念
  • clone: 是个对某个远程仓库的本地拷贝。克隆时,实际上是拷贝整个源存储仓库,包括所有历史记录和分支
  • branch: 是 git 的一种机制,处理单一存储仓库中的变更,并最终目的是用于与其他部分代码合并

找回已经删除的分支

详情看这里

  • 先通过 reflog 找到对应的 SHA1 值
  • 然后通过 git checkout [sha] 切换到这个 SHA1 都应的 commit, 再使用 git checkout -b [branchname] 切换成对应的分支名.或者直接使用 git checkout -b <branch> <sha> 一步到位将对应的 SHA1 值切换成对应的分支

合到 release 或者 hotfix 分支的合并规则

为了保持原有的规则,一般是使用 git checkout release|hotfix; git merge master 的方式合并的

调整 commit 的顺序

Reordering of commits : 使用 git rebase -i <HASH> ,然后调整顺序,善用 ddkP 以及 ddp 命令能有效完成部分操作

git 是否保持文件权限

根据 Does git store the read, write, execute permissions for files , So git stores only the content in the file and the execute bit. ,即仅保持文件的内容和文件是否可执行的状态

如果需要修改已经在 git 仓库中文件的可执行属性,可以使用 update-index 中的 --chmod=+x 或者 --chmod=-x

仅获取当前分支名

这里 git rev-parse --abbrev-ref HEAD

git 提示不在 git 目录下 但是目录存在

  • HEAD 文件的问题,详见 这里 或者 这里 。只需要将 .git/HEAD 文件删除,然后 bash 运行 echo 'ref: refs/heads/master' > .git/HEAD 就行了

仅本地忽略部分文但是不共享到别的用户

编辑 .git/info/exclude 文件,这个文件和 .gitignore 一样的格式。这个的好处是仅仅在你本地忽略了这部分文件,别人对其是不可感知的,如果这部分文件是已经在 git 中管理的,则要使用 git update-index --assume-unchanged <file-list> 让 git 不要追踪他

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

别闹i

暂无简介

0 文章
0 评论
20 人气
更多

推荐作者

忆伤

文章 0 评论 0

眼泪也成诗

文章 0 评论 0

zangqw

文章 0 评论 0

旧伤慢歌

文章 0 评论 0

qq_GlP2oV

文章 0 评论 0

旧时模样

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文