git常用命令

1. 创建仓库命令

  • git init: 初始化仓库就是在当前目录下创建一个.git 目录,用于存储 Git 所需的元数据和文件版本记录。该目录包含了 objects、refs/head、refs/tags 和模板文件等基本部分。

  • git clone [url]: 拷贝一份远程仓库,也就是下载一个项目和它的整个代码历史。

2. 配置

  • git config --list: 显示当前的 Git 配置

  • git config -e [--global]: 编辑 Git 配置文件

  • git config [--global] user.name "[name]" / git config [--global] user.email "[email address]": 设置提交代码时的用户信息

3. 增加/删除文件

  • git add [file1] [file2] ...: 添加指定文件到暂存区

  • git add [dir]: 添加指定目录到暂存区,包括子目录

  • git add .: 添加当前目录的所有文件到暂存区

  • git add -p: 添加每个变化前,都会要求确认,对于同一个文件的多处变化,可以实现分次提交

  • git rm [file1] [file2] ...: 删除工作区文件,并且将这次删除放入暂存区

  • git rm --cached [file]: 停止追踪指定文件,但该文件会保留在工作区

  • git mv [file-original] [file-renamed]: 改名文件,并且将这个改名放入暂存区

4. 代码提交

  • git commit -m [message]: 提交暂存区到仓库区

  • git commit [file1] [file2] ... -m [message]: 提交暂存区的指定文件到仓库区

  • git commit -a: 提交工作区自上次 commit 之后的变化,直接到仓库区

  • git commit -v: 提交时显示所有 diff 信息

  • git commit --amend -m [message]: 使用一次新的 commit,替代上一次提交。如果代码没有任何新变化,则用来改写上一次 commit 的提交信息

  • git commit --amend [file1] [file2] ...: 重做上一次 commit,并包括指定文件的新变化

5. 分支

  • git branch: 列出所有本地分支

  • git branch -r: 列出所有远程分支

  • git branch -a: 列出所有本地分支和远程分支

  • git branch [branch-name]: 新建一个分支,但依然停留在当前分支

  • git checkout -b [branch]: 新建一个分支,并切换到该分支

  • git branch [branch] [commit]: 新建一个分支,指向指定 commit

  • git branch --track [branch] [remote-branch]: 新建一个分支,与指定的远程分支建立追踪关系

  • git checkout [branch-name]: 切换到指定分支,并更新工作区

  • git checkout -: 切换到上一个分支

  • git branch --set-upstream [branch] [remote-branch]: 建立追踪关系,在现有分支与指定的远程分支之间

  • git merge [branch]: 合并指定分支到当前分支

  • git cherry-pick [commit]: 选择一个 commit,合并进当前分支

  • git branch -d [branch-name]: 删除分支

  • git push origin --delete [branch-name] 或 git branch -dr [remote/branch]: 删除远程分支

6. 标签

  • git tag: 列出所有 tag

  • git tag [tag]: 新建一个 tag 在当前 commit

  • git tag [tag] [commit]: 新建一个 tag 在指定 commit

  • git tag -d [tag]: 删除本地 tag

  • git push origin :refs/tags/[tagName]: 删除远程 tag

  • git show [tag]: 查看 tag 信息

  • git push [remote] [tag]: 提交指定 tag

  • git push [remote] --tags: 提交所有 tag

  • git checkout -b [branch] [tag]: 新建一个分支,指向某个 tag

7. 查看信息和历史

  • git status: 显示有变更的文件

  • git log: 显示当前分支的版本历史

  • git log --stat: 显示 commit 历史,以及每次 commit 发生变更的文件

  • git log -S [keyword]: 搜索提交历史,根据关键词

  • git log [tag] HEAD --pretty=format:%s: 显示某个 commit 之后的所有变动,每个 commit 占据一行

  • git log [tag] HEAD --grep feature: 显示某个 commit 之后的所有变动,其”提交说明”必须符合搜索条件

  • git log --follow [file] 或 git whatchanged [file]: 显示某个文件的版本历史,包括文件改名

  • git log -p [file]: 显示指定文件相关的每一次 diff

  • git log -5 --pretty --oneline: 显示过去 5 次提交

  • git shortlog -sn: 显示所有提交过的用户,按提交次数排序

  • git blame [file]: 显示指定文件是什么人在什么时间修改过

  • git diff: 显示暂存区和工作区的差异

  • git diff --cached [file]: 显示暂存区和上一个 commit 的差异

  • git diff HEAD: 显示工作区与当前分支最新 commit 之间的差异

  • git diff [first-branch]...[second-branch]: 显示两次提交之间的差异

  • git diff --shortstat "@{0 day ago}": 显示今天你写了多少行代码

  • git show [commit]: 显示某次提交的元数据和内容变化

  • git show --name-only [commit]: 显示某次提交发生变化的文件

  • git show [commit]:[filename]: 显示某次提交时,某个文件的内容

  • git reflog: 显示当前分支的最近几次提交

8.远程同步

  • git fetch [remote]: 下载远程仓库的所有变动(远程新增或删除分支都能显示)

  • git remote -v: 显示所有远程仓库

  • git config [--global] user.name "[name]" / git config [--global] user.email "[email address]": 设置提交代码时的用户信息

  • git remote show [remote]: 显示某个远程仓库的信息

  • git remote add [shortname] [url]: 增加一个新的远程仓库,并命名

  • git pull [remote] [branch]: 取回远程仓库的变化,并与本地分支合并

  • git push [remote] [branch]: 上传本地指定分支到远程仓库

  • git push [remote] --force: 强行推送当前分支到远程仓库,即使有冲突

  • git push [remote] --all: 推送所有分支到远程仓库

9.撤销

  • git checkout [file]: 恢复暂存区的指定文件到工作区

  • git checkout [commit] [file]: 恢复某个 commit 的指定文件到暂存区和工作区

  • git checkout .: 恢复暂存区的所有文件到工作区

  • git reset [file]: 重置暂存区的指定文件,与上一次 commit 保持一致,但工作区不变

  • git reset --hard: 重置暂存区与工作区,与上一次 commit 保持一致

  • git reset [commit]: 重置当前分支的指针为指定 commit,同时重置暂存区,但工作区不变

  • git reset --hard [commit]: 重置当前分支的 HEAD 为指定 commit,同时重置暂存区和工作区,与指定 commit 一致

  • git reset --keep [commit]: 重置当前 HEAD 为指定 commit,但保持暂存区和工作区不变

  • git revert [commit]: 新建一个 commit,用来撤销指定 commit。后者的所有变化都将被前者抵消,并且应用到当前分支

  • git stash: 暂时将未提交的变化移除,稍后再移入

  • git stash pop: 暂时将未提交的变化移除,稍后再移入

10.其他

  • git archive: 生成一个可供发布的压缩包

  • git repack: 打包未归档文件

  • git count-objects: 计算解包的对象数量

  • git help 或 git --help: Git 帮助,查看 git 相关命令,如果想看某个特定命令的具体细节,可使用 git [命令] –help,如 git commit –help 表示查看提交相关命令的帮助

11. 常见场景

11.1 创建分支

本地创建分支

git checkout -b your_branch

分支推送到远程存储库源并跟踪它

git push -u origin your_branch

11.2 删除分支

本地删除分支的命令

git branch -d "branch name"

请注意,-d 选项是 --delete 的缩写,仅当分支完全合并到其父分支中时才会删除该分支。如果你有未合并的更改,那么它不会删除分支,并且你将收到错误提示。如果要删除分支,无论合并状态如何,都需要强制删除分支。你可以使用以下命令强制删除本地分支

git branch -D <branchName>

删除 Git 远程分支

git push origin -d "branch name”

要确认远程跟踪分支是否被删除,可以运行以下命令:

git branch –remotes
# 可简写为:
git branch –r

11.3 要排除的文件已经被上传到远程 Git 仓库怎么办

mac 有个毒瘤文件就是 DS_Store,如果没有全局排除掉那么上传新项目的时候很容易就被上传。还有一些其他的构建文件如果没有设置好.gitignore 也会被上传。

有的时候排除文件在我们项目过一段时间后才想起来添加,但是那时候远程库已经有了。这个时候即使我们添加排除,远程库中的排除文件也不会被删除。那么我们就需要清除掉远程库的内容。

确保排除文件

我们确保排除文件.gitignore已经编辑完成。

清理 Git 缓存

我们需要清理不必要文件的 Git 缓存。

使用以下命令,这个命令会递归地从缓存中移除所有在 .gitignore 文件中定义的文件和文件夹:

git rm -r --cached .

进行提交

清理完成后我们就可以在 Github 客户端等 GIt 客户端中重新进入 add、commit 等流程了。如果你没有使用客户端,也可以通过代码操作:

git add .
git commit -m "Remove all ignored files and update .gitignore"
git push origin main

11.4 git 撤销已经 push 到远程仓库的 commit

经提交到远程仓库的 commit,想要撤销可以通过 reset 或者 revert 来撤销,使用 reset 撤销时会把撤销的 commit 信息一同删除,revert 撤销时保留 commit 信息生成一个新的撤销的 commit

使用 reset

git reset --hard commit_id 回退到指定 commit,或者git reset --hard HEAD^n 回退到上 n 个 commit

git push -f origin branch_name 提交

放弃本地修改强制拉取最新的 commit

git reset --hard origin/branch_name

11.5 git rebase 和 merge

git merge

git merge 的优势是它保留了分支的结构与历史提交目录,但同时这也导致了提交历史会被大量的 merge 污染

git rebase

rebase 命令是一个经常听到,但是大多数人掌握又不太好的一个命令。rebase 合并往往又被称为 「变基」

它是将把所有的提交压缩成一个 patch 。然后把 patch 添加到目标分支里。rebasemerge 不同的是,rebase 通过为原始分支中的每个提交创建全新的 commits 来重写项目历史记录

master 分支为基,对 feature 分支进行变基:

git checkout feature
git rebase master

git rebase 的优势是可以获得更清晰的项目历史。首先,它消除了 git merge 所需的不必要的合并提交;其次,rebase 会产生完美线性的项目历史记录,你可以在 feature 分支上没有任何分叉的情况下一直追寻到项目的初始提交。

但是, rebase 会丢失合并提交的上下文, 使我们无法看到真实的更改是何时合并到目标分支上的

交互式 Rebase

这个命令比 git rebase 更为强大,它将会在 commits 移动到新分支时更改这些 commits ,通常,这用于在合并 feature 分支到 master 之前清理其杂乱的历史记录。

git checkout feature
git rebase -i master

这将打开一个文本编辑器,列出即将移动的所有提交:

pick 6633b5a Message for commit #1
pick 3a03f0d Message for commit #2
pick 657897b Message for commit #3

它清晰地展示了分支在 rebase 后的样子。通过重新调整,提交历史可以变成任何你想要的样子。

消除这种无意义的提交使你的功能历史更容易理解。这是 git merge 根本无法做到的事情。

至于 commits 条目前的 pickfixupsquash 等命令,在 git 目录执行 git rebase -i 即可查看到,大家按需重排或合并提交即可,注释说明非常清晰,在此不做过多说明

git merge vs git rebase

  • git merge:

    • 记录下合并动作,很多时候这种合并动作是垃圾信息
    • 不会修改原 commit ID
    • 冲突只解决一次
    • 分支看着不大整洁,但是能看出合并的先后顺序
    • 记录了真实的 commit 情况,包括每个分支的详情
  • git rebase:

    • 改变当前分支 branch out 的位置
    • 得到更简洁的项目历史
    • 每个 commit 都需要解决冲突
    • 修改所有 commit ID