git 常用命令_git常用命令
文章目录
- config
-
- 1. 临时修改用户名和邮箱
- 2. 全局修改用户名和邮箱
- remote
-
- 1. 查看当前远程地址
- 2. 修改远程地址
- 3. 验证修改
- 4. 推送到新地址
- 5. 添加或替换其他远程地址
- 6. 删除远程地址
- 总结
- clone
- .gitignore
-
- 语法规则
-
- 忽略指定文件或目录
- 忽略某种类型的文件
- 使用 ! 例外规则
- 使用 / 指定目录
- 使用 ** 进行递归匹配
- 生效规则
-
- 已经被 Git 跟踪的文件不会被忽略
- 如何检查某个文件是否被忽略
- 总结
- commit
-
- 修改最近一次提交中的文件(未 push)
- 修改更早之前的某个提交(未 push)
- 修改已经 push 到远程的提交
- reset
-
- 1. 丢弃已暂存的修改
- 2. 丢弃工作区的修改
- 3. 一步完成(同时丢弃暂存区和工作区的修改)
- 4. 取消最近的 commit(保留文件变更)
- 5. 取消最近的 commit(不保留文件变更)
- 6. 取消指定的 commit(回退到某个历史提交)
- 7. 撤销已推送到远程的 commit(强制推送)
- 8. 撤销已提交但未推送的 commit(更改提交信息)
- 总结
- revert
-
- 使用`git revert`与`git reset`的比较
- clean
-
- 1. 删除所有未追踪文件
- 2. 删除未追踪的目录
- 3. 删除未追踪的文件和忽略文件
- 4. 仅查看即将删除的文件(安全检查)
- 5. 仅删除某个文件或目录
- 总结
- branch
-
- 1. 查看分支
- 2. 创建分支
- 3. 重命名分支
- 4. 切换分支
- 5. 删除分支
- 6. 合并分支
- 7. 推送分支
- 8. 重命名分支
- 9. 分支比较
- 10. 分支管理常见流程
- 总结
- merge
-
- 1. 基本概念
- 2. 合并的基本步骤
- 3. 合并模式
-
- 3.1 快进合并 (Fast-Forward Merge)
- 3.2 三方合并 (3-Way Merge)
- 4. 常用选项
-
- 4.1 --squash
- 4.2 --abort
- 5. 冲突处理
- 6. 示例:从开发分支合并到主分支
- rebase
-
- 1. git rebase 的基本用法
-
- 基础 rebase
- 拉取远程代码时使用 rebase
- 2. 交互式 rebase(git rebase -i)
-
- 合并提交(squash & fixup)
- 修改某个提交(edit)
- 删除某个提交
- 3. rebase 解决冲突
- 4. git rebase 高级用法
-
- 变基远程分支
- 将分支变基到另一分支
- 合并多个分支提交
- 5. rebase 发生问题时的撤销
- 总结
- cherry-pick
-
- 1. 用法
- 2. 提交多个hash
-
- 2.1 挑选一组不连续的提交
- 2.2 暂停的 Cherry-Pick
- 3. cherry-pick 选项
-
- 3.1 -e / --edit
- 3.2 -n / --no-commit
- 3.3 -x
- rm
-
- 1. 常用操作
-
- 1.1 删除文件并将其从暂存区移除
- 1.2 只从暂存区移除文件,保留本地文件
- 2. 选项详解
-
- 2.1 `--cached`
- 2.2 `-f` 或 `--force`
- 2.3 `-r`
- 3. 注意事项
-
- 3.1 删除的文件如何恢复?
- 3.2 `.gitignore` 的配合使用
- 总结
- tag
-
- 1. 查看现有标签
- 2. 创建附注标签
- 3. 给特定的提交打标签
- 4. 推送标签到远程仓库
- 5. 删除标签
- 6. 检查标签详细信息
- 7. 拉取标签
- 8. 拉取标签和代码的区别
- 9. 检出到某个标签
- stash
-
- `git stash`
- `git stash list`
- `git stash show`
- `git stash apply`
- `git stash pop`
- `git stash drop stash@{n}`
- `git stash clear`
- log
-
- 常用命令
-
- 查看特定文件的提交记录
- 查看某个分支的提交记录
- 显示提交历史的分支结构
- 统计提交次数
- 仅查看文件变更
- 格式化日志
- 结合 grep 搜索提交
- 全面查看提交历史
- 查看提交内容
- 总结
- show和diff 区别
-
- git show
- git diff
- 区别总结
- submodule
-
- 什么是子仓库?
- 常用操作
-
- 1.添加子仓库
- 2. 初始化子仓库
- 3. 更新子仓库
- 4. 删除子仓库
- .gitmodules 文件详解
- 常见问题
-
- 子仓库未初始化如何解决?
- 取消子仓库在主仓库中的未追踪中展示
- 问题记录
-
- Gitee exceeds quota 100MB
config
1. 临时修改用户名和邮箱
如果只需要修改当前仓库的提交者信息,可以使用以下命令:
git config user.name \"新用户名\"git config user.email \"新邮箱地址\"
查看配置:
git config user.namegit config user.email
注意:此修改仅对当前仓库有效,不会影响全局配置或其他仓库。
2. 全局修改用户名和邮箱
如果希望更改所有仓库的默认用户名和邮箱,可以使用全局配置:
git config --global user.name \"新用户名\"git config --global user.email \"新邮箱地址\"
查看全局配置:
git config --global user.namegit config --global user.email
remote
1. 查看当前远程地址
git remote -v
输出示例:
origin https://github.com/user/old-repo.git (fetch)origin https://github.com/user/old-repo.git (push)
2. 修改远程地址
修改 origin
的 URL
git remote set-url origin <new-remote-url>
示例:
git remote set-url origin https://github.com/user/new-repo.git
3. 验证修改
再次查看远程地址,确保已经更改成功:
git remote -v
输出示例:
origin https://github.com/user/new-repo.git (fetch)origin https://github.com/user/new-repo.git (push)
4. 推送到新地址
验证后,你可以尝试推送代码到新的远程仓库:
git push origin main
5. 添加或替换其他远程地址
添加新的远程地址:
如果需要保留旧的远程地址并添加新的远程仓库,可以使用以下命令:
git remote add <name> <new-remote-url>
示例:
git remote add upstream https://github.com/user/another-repo.git
查看多个远程:
git remote -v
输出示例:
origin https://github.com/user/new-repo.git (fetch)origin https://github.com/user/new-repo.git (push)upstream https://github.com/user/another-repo.git (fetch)upstream https://github.com/user/another-repo.git (push)
6. 删除远程地址
git remote remove <name>
总结
git remote -v
git remote set-url origin
git remote add
git remote remove
clone
克隆仓库
首先,使用 git clone
命令克隆整个仓库到你的本地机器。如果你只想克隆特定的分支,而不是克隆整个仓库的所有分支和历史记录,可以使用 --branch
或 -b
选项指定分支名。
git clone -b <branch-name> <repository-url># 例如,如果你想克隆一个名为 feature-x 的分支:git clone -b feature-x https://github.com/user/repo.git
.gitignore
语法规则
.gitignore
文件的每一行都表示一个忽略规则。以下是 .gitignore
规则的基本语法
忽略指定文件或目录
- 忽略某个文件
myfile.txt
忽略
myfile.txt
文件 - 忽略某个目录(及其所有内容)
mydir/
忽略
mydir
目录及其所有子文件。
忽略某种类型的文件
- 忽略所有 .log 结尾的日志文件:
*.log
忽略所有
.log
文件,如error.log
、debug.log
。
使用 ! 例外规则
可以使用 !
号来排除某些文件,即即使符合上面的规则,也不要忽略这些文件。
- 忽略
logs
目录下的所有.log
文件,但important.log
除外logs/*.log!logs/important.log
这个规则的意思是:忽略
logs
目录下的.log
文件,但important.log
例外,不会被忽略。
使用 / 指定目录
/
表示相对.gitignore
文件所在目录的路径/node_modules/
这只会忽略仓库根目录下的
node_modules/
目录,而不会影响子目录下的node_modules/
。- 不使用
/
,则匹配所有层级的node_modules/
node_modules/
这会忽略所有
node_modules/
目录,包括子目录下的node_modules/
。
使用 ** 进行递归匹配
-
** 表示匹配任意目录
**/temp/
这会忽略所有
temp/
目录,不管它位于哪个层级。 -
忽略所有 .log 文件,不论在哪个子目录:
**/*.log
这会忽略整个项目中所有
.log
文件。
生效规则
已经被 Git 跟踪的文件不会被忽略
如果一个文件已经被 Git
跟踪,即使 .gitignore
规则匹配它,也不会被忽略。
解决方案: 如果你想让 .gitignore
规则对已经被 Git
跟踪的文件生效,你需要先将它从 Git
追踪中移除:
git rm -r --cached <file_or_directory># 例如git rm -r --cached node_modules/# 然后提交更改:git commit -m \"更新 .gitignore 规则\"git push origin main
如何检查某个文件是否被忽略
你可以使用 git check-ignore
命令来检查某个文件是否会被 .gitignore
忽略
git check-ignore -v <file># 例如 如果 debug.log 在 .gitignore 规则中,它会返回匹配的规则git check-ignore -v logs/debug.log
总结
.gitignore
用于忽略不需要提交的文件,避免污染Git
仓库。- 规则包括:忽略单个文件、目录、文件类型、特定层级目录等。
- 可以使用
!
例外规则来指定不被忽略的文件。 - 规则一旦生效,必须先用
git rm --cached
移除已被Git
追踪的文件,否则.gitignore
不会生效。 - 使用
git check-ignore -v
进行调试,确认文件是否被忽略。
掌握 .gitignore
规则可以帮助你更高效地管理 Git
仓库,提高团队协作的效率。
commit
修改最近一次提交中的文件(未 push)
如果你刚提交,发现文件有错,想修改并更新到上一次提交:
# 修改文件,编辑保存vim your_file.txt# 添加修改git add your_file.txt# 修改最近一次提交,合并新的更改git commit --amend
git commit --amend
会把你的修改追加到上一次提交里,修改提交信息时会打开编辑器,你也可以用-m \"new message\"
直接写提交信息。
修改更早之前的某个提交(未 push)
如果你想修改历史上某个提交:
git rebase -i <commit_id>^
- 会进入交互式界面,找到你想修改的提交,把
pick
改成edit
- 保存退出后,Git 会停在那个提交,你可以修改文件:
vim your_file.txtgit add your_file.txtgit commit --amend
- 然后继续 rebase
git rebase --continue
修改已经 push 到远程的提交
如果修改的提交已经推送到远程仓库(尤其是公共分支),需要谨慎操作,因为这会重写历史,可能导致别人拉取代码冲突。
- 操作同上,完成修改后强制推送:
git push --force
⚠️ 注意:请确保所有协作者都知道这一操作!
reset
在 Git 中,如果你已经执行了 git add,将文件的更改暂存到索引区,但又想丢弃这些修改,可以通过以下步骤实现
1. 丢弃已暂存的修改
git reset HEAD <file>
或者丢弃所有已暂存的文件
git reset HEAD
作用:
git reset HEAD
会将指定文件从暂存区移回工作区,修改仍然保留在工作区中,但不会再被标记为已暂存。
示例:git reset HEAD myfile.txt
此命令将
myfile.txt
的修改移出暂存区
2. 丢弃工作区的修改
在执行完
git reset HEAD
后,如果还想丢弃工作区的更改,可以使用以下命令
git checkout -- <file>
或者丢弃所有文件的更改
git checkout -- .
作用:
git checkout --
会将文件恢复到上一次提交时的状态,丢弃工作区中的修改
3. 一步完成(同时丢弃暂存区和工作区的修改)
如果想直接同时丢弃暂存区和工作区的所有修改,可以使用以下命令
git reset --hard HEAD
作用:
- 此命令将工作区和暂存区重置到最后一次提交的状态,所有未提交的更改都会被丢弃。
- ⚠️ 注意:此命令会直接丢弃所有未提交的修改,不可恢复,操作前请确认没有重要内容。
4. 取消最近的 commit(保留文件变更)
这个命令会取消最新的提交,但保留修改,使其回到暂存区。
如果你只想取消最近的 commit
,但是保留这些文件的修改(即将这些修改放回暂存区)
git reset --soft HEAD~1
--soft
:将HEAD
指针回退到前一个提交(即HEAD~1
),但是保留工作区和暂存区的变更,变 更会被放回到暂存区。HEAD~1
:表示上一个提交。
5. 取消最近的 commit(不保留文件变更)
这会完全删除最近的提交,包括你在工作区和暂存区的所有变更,因此要小心使用。
如果你希望取消最近的 commit
,并且不保留任何修改(即删除这些更改)
git reset --hard HEAD~1
--hard
:将 HEAD 回退到前一个提交,并丢弃工作区和暂存区的所有更改。
6. 取消指定的 commit(回退到某个历史提交)
这个命令会将
HEAD
指针和分支指针回退到指定的提交,并且丢弃回退后所有的提交。
如果你想取消某个历史提交,而不是仅仅取消最新的 commit
git reset --hard <commit_id>
:是你希望回退到的目标提交的哈希值(例如
a1b2c3d4
)。
7. 撤销已推送到远程的 commit(强制推送)
警告:强制推送会修改远程仓库的历史,可能会影响其他协作开发者的代码,因此必须谨慎操作,最好在团队中协调好后再执行。
如果你已经将 commit
推送到远程仓库,并且想撤销这些提交,需要谨慎操作。假设你已经执行了某些 commit
,并推送到远程仓库。你可以通过以下步骤取消这些提交并强制推送。
# 首先,使用 git reset 取消本地的提交:git reset --hard HEAD~1# 然后,使用 git push 强制推送到远程仓库:git push origin <branch_name> --force
8. 撤销已提交但未推送的 commit(更改提交信息)
这将允许你修改最新提交的提交信息,而不需要重新提交更改。修改完提交信息后,保存并退出编辑器,新的提交信息将会生效。
如果你仅想修改提交信息,而不想撤销整个提交,可以使用 git commit --amend
来修改最近的提交:
git commit --amend
总结
git reset HEAD
git reset HEAD → git checkout --
git reset --hard HEAD
git reset --soft HEAD~1
git reset --hard HEAD~1
git reset --mixed HEAD~1
git reset --hard
git commit --amend
revert
git revert
命令用于创建一个新的commit
,该commit
会撤销指定commit
的更改。这种方法不会改变历史,而是在历史中添加一个新的commit
来抵消之前的更改。
例如,要回滚到HEAD~3
(即当前commit
的前三个commit
),可以执行以下命令:
git revert HEAD~3
这会打开默认的文本编辑器,要求你输入提交信息。输入完毕后保存并退出,Git将创建一个新的commit
,撤销HEAD~3
的更改。
使用git revert
与git reset
的比较
git revert
:创建一个新的commit
来撤销之前的更改,不改变历史。适用于公共仓库,因为它不会破坏其他人的工作。
git reset
:移动HEAD
指针到指定commit
,可以选择性地更改索引和工作目录。可能会改变历史,因此不适用于公共仓库。
clean
在 Git
中,丢弃未追踪(未纳入版本控制)
的文件,即 删除本地未添加到 Git
的文件,可以使用以下命令
1. 删除所有未追踪文件
git clean -f
-
-f
(--force
):强制删除未追踪的文件(未git add
的文件)。 -
⚠️ 注意:此操作不可撤销,执行前请确保不误删重要文件!
2. 删除未追踪的目录
如果未追踪的文件在目录下,并且要删除整个目录:
git clean -fd
-d
:删除未追踪的目录。
3. 删除未追踪的文件和忽略文件
如果你希望连 .gitignore
里被忽略的文件也一并删除:
git clean -xfd
-x
:删除 所有未追踪的文件,包括.gitignore
里忽略的文件。
4. 仅查看即将删除的文件(安全检查)
在执行删除前,建议先用 -n
选项进行检查
git clean -n
示例输出:
Would remove temp.txtWould remove logs/debug.log
确认后再执行 git clean -f 进行删除!
5. 仅删除某个文件或目录
如果你只想删除特定的未追踪文件或目录,例如 temp.txt
:
git clean -f temp.txt
或者删除 logs/
目录:
git clean -fd logs/
总结
git clean -n
git clean -f
git clean -fd
git clean -xfd
.gitignore
里的文件。git clean -f
🚀 建议先执行 git clean -n
确认文件后,再执行 git clean -f
避免误删!
branch
在 Git 中,分支操作是项目开发中非常常见的任务。以下是关于分支操作的常用命令及详细说明。
1. 查看分支
# 查看本地分支git branch# 查看远程分支git branch -r# 查看本地和远程分支git branch -a
2. 创建分支
# 创建分支git branch <branch_name># 创建新分支并且切换到该分支git checkout -b <branch_name>
3. 重命名分支
git branch -m 旧分支 新分支
4. 切换分支
# 切换到指定分支git checkout <branch_name># 指定提交切换分支git checkout <branch_name> <commit_hash>
5. 删除分支
# 删除本地分支(只适用于已合并的分支)git branch -d <branch_name># 强制删除本地分支 (未合并的也会被删除)git branch -D <branch_name># 删除远程分支git push origin --delete <branch_name>
6. 合并分支
# 将指定分支合并到当前分支git merge <branch_name>
合并冲突处理:
- Git 会提示冲突文件。
- 编辑冲突文件,解决冲突。
- 将修改后的文件标记为解决:
git add <file>
- 完成合并
git commit -m <desc>
7. 推送分支
git push origin <branch_name>
8. 重命名分支
# 重命名当前分支git branch -m <new_branch_name># 重命名指定分支git branch -m <old_branch_name> <new_branch_name>
9. 分支比较
git diff <branch_1> <branch_2>
10. 分支管理常见流程
开发新功能
- 创建新分支:
git switch -c feature/new-feature
- 开发并提交代码:
git add .git commit -m \"Add new feature\"
- 推送新分支到远程:
git push origin feature/new-feature
合并分支到主分支
- 切换到主分支:
git switch main
- 拉取最新代码:
git pull origin main
- 合并功能分支:
git merge feature/new-feature
- 删除功能分支(可选):
git branch -d feature/new-featuregit push origin --delete feature/new-feature
总结
查看分支
git branch
创建分支
git branch
切换分支
git switch
git branch -d
合并分支
git merge
推送分支
git push origin
跟踪分支
git branch --set-upstream-to=origin/
merge
git merge
是 Git 中用于将多个分支的内容合并到一个分支的操作。它是团队协作开发中处理分支合并的核心命令之一。
1. 基本概念
git merge
的作用:将另一个分支的更改整合到当前分支。- 合并的前提:必须在某个分支上运行
git merge
命令,目标是将另一个分支的更改合并到当前分支。
2. 合并的基本步骤
- 切换到目标分支(合并到哪个分支):
git checkout <target-branch># 或者更常用的方式:git switch <target-branch>
- 执行合并:
# 将 source-branch 的更改合并到 target-branch。git merge <source-branch>
- 解决冲突(如有):
- 如果合并过程中有冲突,Git 会提示哪些文件有冲突。
- 手动编辑冲突的文件,解决冲突后执行:
git add <conflicted-file>git commit
3. 合并模式
git merge
主要有两种模式:快进合并(Fast-Forward) 和 三方合并(3-Way Merge)。
3.1 快进合并 (Fast-Forward Merge)
- 条件:如果当前分支的 HEAD 是目标分支的祖先(没有分叉历史)。
- 结果:直接将 HEAD 移动到目标分支的最新提交,历史记录呈直线。
示例:
# 假设分支状态如下:# main: A -> B# feature: A -> B -> Cgit switch maingit merge feature# 合并后:# main: A -> B -> C
特点:
- 不会生成额外的合并提交。
- 合并历史简单清晰,但不适合需要保留分支开发历史的情况。
3.2 三方合并 (3-Way Merge)
- 条件:如果当前分支和目标分支都有各自的提交记录(有分叉历史)。
- 结果:创建一个新的合并提交,记录两个分支的历史。
示例:
# 假设分支状态如下:# main: A -> B# feature: A -> Cgit switch maingit merge feature# 合并后:# main: A -> B -> D (merge commit)# ↘ C
特点:
- 生成一个合并提交,记录了两个分支的提交历史。
- 更适合复杂的分支开发场景。
4. 常用选项
git merge
支持多种选项来满足不同场景的需求:
4.1 --squash
- 将另一个分支的所有提交压缩为一个提交,然后合并到当前分支。
- 常用于临时分支开发,将多个提交压缩成一个干净的提交。
示例:
git merge --squash featuregit commit -m \"Merge feature branch\"
结果: 不会保留 feature
分支的提交历史,只会将更改作为一个新提交合并。
4.2 --abort
- 如果在合并过程中遇到冲突且不想继续合并,可以使用此选项终止合并并恢复到合并前的状态。
示例:
git merge feature# 如果冲突了,不想继续:git merge --abort
5. 冲突处理
在合并过程中,如果文件在两个分支中都有修改,可能会发生冲突。
冲突解决步骤:
- 查看冲突文件:
git status
- 编辑冲突文件: 手动修改文件,确保内容符合需求。冲突部分通常标记为:
<<<<<<< HEAD# 当前分支的更改=======# 合并分支的更改>>>>>>> feature
- 标记冲突已解决: 修改后添加到暂存区:
git add <file>
- 提交合并结果:
git commit
6. 示例:从开发分支合并到主分支
# 创建开发分支git checkout -b dev# 在开发分支进行提交echo \"Some changes\" > file.txtgit add file.txtgit commit -m \"Make some changes\"# 切回主线分支合并git switch maingit merge dev# 检测历史git log --oneline --graph
rebase
git rebase
是 Git
中用于变基(rebase
)操作的命令,主要用于重写提交历史,以保持提交记录的整洁,并避免不必要的合并提交(merge commit
)。在多人协作时,它有助于保持线性历史,使代码变更更清晰。
1. git rebase 的基本用法
基础 rebase
将当前分支的提交移动到 main 分支的最新提交之后
git checkout feature-branch # 切换到开发分支git rebase main # 让 feature-branch 变基到 main 最新提交上
等价于:
-
git fetch
获取最新的远程main
分支。 -
把
feature-branch
上的提交一个个“摘下来”。 -
在
main
最新提交上重新应用这些提交。
示例
假设当前 git log --oneline --graph
结构如下:
A---B---C (main) \\ D---E (feature-branch)
运行:
git checkout feature-branchgit rebase main
变为:
A---B---C---D\'---E\' (feature-branch)
即:这会“重放” D、E 提交到 main 的末尾,提交哈希变了。
拉取远程代码时使用 rebase
git pull --rebase origin main
等价于:
git fetch origingit rebase origin/main
-
作用:避免
merge commit
,保持干净的提交历史。 -
适用于: 多人协作时更新远程代码,保持提交线性。
2. 交互式 rebase(git rebase -i)
交互式 rebase
允许你修改多个提交,如合并(squash)、编辑(edit)、删除(drop)、重新排序等。
git rebase -i HEAD~3
这表示对最近 3 次提交执行交互式变基,Git 会打开一个交互界面:
pick abc123 First commitpick def456 Second commitpick ghi789 Third commit
你可以修改 pick
为:
pick
reword
commit message
)。edit
squash
commit message
。fixup
commit message
。drop
合并提交(squash & fixup)
场景:多个提交可以合并为一个
pick abc123 First commitsquash def456 Second commitfixup ghi789 Third commit
-
squash
:合并到上一个提交,并允许修改commit message
。 -
fixup
:合并到上一个提交,并丢弃自己的commit message
。
修改某个提交(edit)
如果 C2
提交有错误但 C3
是正确的:
pick abc123 First commitedit def456 Second commitpick ghi789 Third commit
然后
git commit --amend # 修改 C2 的内容git rebase --continue # 继续 rebase
删除某个提交
pick abc123 First commitdrop def456 Second commit # 删除该提交pick ghi789 Third commit
3. rebase 解决冲突
当 rebase
过程中发生冲突,Git 会提示:
CONFLICT (content): Merge conflict in file.txt
解决步骤:
- 手动解决冲突,修改相关文件。
- 标记已解决
git add <冲突文件>
- 继续
rebase
git rebase --continue
- 如果不想继续
rebase
,可以取消git rebase --abort
4. git rebase 高级用法
变基远程分支
git checkout feature-branchgit fetch origingit rebase origin/main
适用于: 让本地 feature-branch
基于最新的 main
。
将分支变基到另一分支
git rebase --onto new-base old-base feature-branch
等价于:
-
找到
feature-branch
相对于old-base
的提交 -
将这些提交应用到
new-base
上
示例
当前 git log
:
A---B---C (old-base) \\ D---E---F (feature-branch)
执行
git checkout feature-branchgit rebase --onto new-base old-base
变为:
A---B---C (old-base) \\ X---Y---Z (new-base) \\ D\'---E\'---F\' (feature-branch)
即:feature-branch
从 new-base
继续,而不再基于 old-base
。
合并多个分支提交
git checkout feature-branchgit rebase --onto main develop feature-branch
这会把 feature-branch
上相对于 develop
的提交,变基到 main
分支上。
5. rebase 发生问题时的撤销
git rebase --abort
rebase
,回到原来的状态。git rebase --continue
rebase
。git rebase --skip
rebase
。总结
git rebase main
main
重新整理提交。git rebase -i HEAD~3
3
次提交。git pull --rebase
rebase
方式拉取远程更新,避免 merge commit
。git rebase --onto new-base old-base feature-branch
feature-branch
从 old-base
变基到 new-base
。git rebase --abort
rebase
并回到原状态。cherry-pick
git cherry-pick
是 Git 中用于 选择性应用某个或多个提交 的命令。它允许你从一个分支中挑选特定的提交并应用到当前分支,而不需要合并整个分支。
1. 用法
git cherry-pick <commitHash>
git cherry-pick
命令的参数,不一定是提交的哈希值,分支名也是可以的,表示引入该分支的最新提交
# 将feature分支的最近一次提交,引入到当前分支git cherry-pick feature
2. 提交多个hash
git cherry-pick <start-commit-hash>^..<end-commit-hash>
- 是起始提交的哈希值。
- 是结束提交的哈希值。
示例
git cherry-pick a1b2c3d4^..d4e5f6g7
这会挑选从 a1b2c3d4
开始到 d4e5f6g7
的所有提交。
2.1 挑选一组不连续的提交
git cherry-pick <commit-hash1> <commit-hash2> <commit-hash3># 示例git cherry-pick 1a2b3c4d 5e6f7g8h 9i0j1k2l
2.2 暂停的 Cherry-Pick
如果你在挑选多个提交时发生冲突,可以使用以下命令进行恢复或终止:
- 查看当前的 Cherry-Pick 状态:
git status
- 如果解决了冲突,继续 Cherry-Pick:
git cherry-pick --continue
- 如果放弃 Cherry-Pick:
git cherry-pick --abort
3. cherry-pick 选项
3.1 -e / --edit
# 在提交前允许修改提交信息git cherry-pick -e <commit-hash>
3.2 -n / --no-commit
只应用更改,不创建新的提交。这允许你将多个提交的更改合并到一个提交中:
git cherry-pick -n <commit-hash>
示例:
- 挑选多个提交,但不提交
git cherry-pick -n 1a2b3c4d 5e6f7g8h
- 合并这些更改并创建一个提交
git commit -m \"Combined changes from specific commits\"
3.3 -x
在生成的提交信息中添加原始提交的引用,方便追溯
git cherry-pick -x <commit-hash># 生成的提交信息会附加类似以下内容(cherry picked from commit 1a2b3c4d)
rm
git rm
是 Git 中用于 移除文件 的命令。通过此命令,可以将文件从 工作区 和 暂存区 一并删除,同时记录删除操作以便在下次提交时生效。
1. 常用操作
1.1 删除文件并将其从暂存区移除
# 1. 从 暂存区 和 工作区 一并移除文件# 2. 下次提交后,删除会被记录在 Git 历史中git rm <file># 示例git rm file.txtgit commit -m \"Remove file.txt\"
1.2 只从暂存区移除文件,保留本地文件
# 文件从 暂存区 移除,但仍保留在本地工作区中# 通常用于将文件从版本控制中忽略(例如文件已错误地加入版本控制)git rm --cached <file># 示例git rm --cached config.jsongit commit -m \"Stop tracking config.json\"
2. 选项详解
2.1 --cached
只从暂存区移除文件,不删除工作区中的文件。
适用场景:
- 停止跟踪某个文件,但不删除本地文件。
- 通常与
.gitignore
配合使用。
示例
git rm --cached file.txt
2.2 -f
或 --force
强制删除文件,适用于已修改且未提交的文件
默认行为:
- 如果文件被修改但未提交,
git rm
会报错以保护未保存的更改。 - 使用
-f
可以跳过此保护。git rm -f file.txt
2.3 -r
递归删除目录及其内容。
适用场景:
- 删除整个目录时,必须使用 -r。
3. 注意事项
3.1 删除的文件如何恢复?
如果误删了文件,可以通过 git checkout
或 git restore
恢复:
- 如果文件还在版本控制中
git restore file.txt
- 如果文件已经被提交删除
git checkout <commit-hash> -- file.txt
3.2 .gitignore
的配合使用
删除文件后,如果希望 Git 永久忽略文件,可以将其加入 .gitignore
文件
操作步骤:
- 停止跟踪文件:
git rm --cached file.txt
- 将文件加入
.gitignore
:echo \"file.txt\" >> .gitignore
- 提交更改:
git add .gitignoregit commit -m \"Ignore file.txt\"
总结
# 删除单个文件git rm old_file.txtgit commit -m \"Remove old_file.txt\"# 删除整个目录git rm -r old_directorygit commit -m \"Remove old_directory\"# 从暂存区移除文件但保留本地文件git rm --cached config.jsongit commit -m \"Untrack config.json\"
tag
在 Git 中,标签(Tag) 是用来给特定的提交点打上一个易于识别的标记,通常用于标识版本(如 v1.0.0)。
1. 查看现有标签
git tag
2. 创建附注标签
git tag -a <tag_name> -m \"\"
例如
git tag -a v1.0.0 -m \"Release version 1.0.0\"
3. 给特定的提交打标签
默认情况下,标签会打在当前的提交上。如果需要给某个特定的提交打标签,可以指定提交的哈希值。
git tag <tag_name> <commit_hash>
例如
git tag v1.0.0 9fceb02git tag -a v1.0.0 9fceb02 -m \"Release version 1.0.0\"
4. 推送标签到远程仓库
创建的标签默认只存在于本地,需要手动推送到远程仓库。
- 推送单个标签:
git push origin <tag_name>
例如
git push origin v1.0.0
- 推送所有标签:
git push origin --tags
5. 删除标签
- 删除本地标签
git tag -d <tag_name>
例如
git tag -d v1.0.0
- 删除远程标签
git push origin --delete <tag_name>
例如
git push origin --delete v1.0.0
6. 检查标签详细信息
git show <tag_name>
7. 拉取标签
默认情况下,执行 git fetch
命令时,Git 不会自动拉取标签。需要显式指定拉取标签。
拉取所有标签
git fetch --tags
8. 拉取标签和代码的区别
- 如果你只想拉取标签,不同步代码
git fetch origin --tags
- 如果你想拉取所有代码和标签
git pull --tags
9. 检出到某个标签
标签本身是静态的快照,不能直接修改代码。要检出到一个标签对应的提交,可以运行以下命令
git checkout <tag_name>
例如
git checkout v1.0.0
注意:检出标签后,Git 会进入 分离头指针状态(detached HEAD),你无法直接提交新代码。如果需要修改代码,可以创建一个新分支:
git checkout -b <new_branch_name>
stash
git stash
是 Git 中用于临时保存当前工作进度的命令。它特别适用于需要切换分支或者处理其他紧急任务时,不想丢失当前未提交的修改。下面我会详细介绍 git stash
的用法和常见场景。
git stash
这个命令会将当前工作目录和暂存区的更改(包括已暂存和未暂存的)保存起来,并恢复工作区到最近一次提交的状态。
未跟踪文件:
git stash
默认只会保存已跟踪的文件的修改,不会保存新创建的未跟踪文件。如果你希望同时保存未跟踪文件,需要使用git stash -u
(或者git stash --include-untracked
)。
# 执行后,Git 会把当前的修改保存到栈中,并清空工作目录和暂存区。git stash# 默认情况下,git stash 只会保存已跟踪文件的更改。# 如果你有一些未跟踪的文件(如新创建的文件),可以使用 -u 参数将它们也一起保存。git stash -u# 你可以在保存时给 stash 添加一个描述信息,这有助于你以后更好地识别每个 stash。git stash save \"修复登录页面的样式\"
git stash list
这个命令会列出所有的 stash
条目,每个 stash
条目都有一个编号 stash@{n}
,n
从 0 开始递增
git stash list# 输出stash@{0}: WIP on master: 6b1d3e5 修复登录页面样式stash@{1}: WIP on dev: 9a8b2f4 添加功能模块
git stash show
查看某个 stash 的详细内容。你可以使用 stash@{n}
来查看特定的 stash。
git stash show stash@{0}# 如果你想查看更详细的差异信息,可以加上 -p 参数:git stash show -p stash@{0}
git stash apply
将某个 stash 应用到当前工作目录。应用时,stash 并不会从栈中删除,它仍然保留。
git stash apply \"stash@{1}\"# 如果你想应用最新的 stash,可以省略 stash@{n},直接使用:git stash apply 1
git stash pop
类似于 git stash apply
,但是会把应用的 stash 从栈中删除。通常用于你确认不再需要该 stash 时。
git stash pop
git stash drop stash@{n}
删除指定的 stash 项目。
git stash drop \"stash@{0}\"
git stash clear
清空所有的 stash 项目。
git stash clear
log
常用命令
# 查看最近一个周的提交日志git log --pretty=format:\'%h %ad %an %s\' --author=xxx --since=7.days# 格式化日志并展示所有提交git log --pretty=format:\'%h %ad %an %s\' --graph --all -20# 表格显示所有提交git log --graph -all -2
git log --oneline# 示例1234567 Initial commitabcdef1 Add README file789abcd Fix bug in calculation#查看从 2024 年 11 月 1 日到 2024 年 11 月 20 日的提交记录。git log --since=\"2024-11-01\" --until=\"2024-11-20\"# 查看最近三天提交git log --since=\"3 days ago\"# 或者git log --since=3.days
查看特定文件的提交记录
git log <文件名># 示例git log README.md
查看某个分支的提交记录
git log branch-name# 示例git log feature-branch
显示提交历史的分支结构
git log --graph# 示例git log --oneline --graph --all# 输出* 789abcd (HEAD -> main) Fix bug in calculation| * abc1234 (feature-branch) Add new feature|/* 1234567 Initial commit
统计提交次数
- 统计最近一周内每个人的提交次数:
git shortlog -s -n --since=\"1 week ago\"
输出:
10 Alice 5 Bob 3 Charlie
- 统计某个用户的提交次数:
git log --author=\"Alice\" --since=\"1 week ago\" --oneline | wc -l
仅查看文件变更
查看最近 7 天内修改的文件:
git log --since=\"7 days ago\" --name-only --pretty=format:\"\"
格式化日志
自定义格式
git log --pretty=format:\"%h - %an, %ar : %s\"
- %h:提交短哈希。
- %an:作者名。
- %ar:相对时间(如 “2 weeks ago”)。
- %s:提交信息。
- %ad: 当前时间
git log --pretty=format:\"%h %an %ad %s\" --date=short# 输出1234567 Alice 2024-11-20 Initial commitabcdef1 Bob 2024-11-19 Add README file
结合 grep 搜索提交
git log --grep=\"关键字\"# 示例git log --grep=\"fix\"git log --author=\'作者\'
全面查看提交历史
查看所有分支的提交历史(简洁格式 + 图形化 + 全部分支)
git log --oneline --graph --all# 查看最近 10 条提交的详细改动内容git log -p -n 10
查看提交内容
# 显示一条的提交差异git log --patch -1# 或git log -p -1# 显示修改行数git log --stat -1
总结
git log
git log --oneline
git log -p
git log
git log --stat
git log --graph
git log --pretty=format:\"%h - %an, %ar : %s\"
git log --grep=\"关键字\"
show和diff 区别
git show
和 git diff
都是用来查看代码变更的 Git 命令,但它们的用途和输出内容有所不同。
git show
- 用途: 用于显示某个特定提交的详细信息,包括提交的元数据(提交信息、作者、日期)以及该提交的具体变更(修改了哪些文件,哪些行被修改)。
- 输出内容:
- 提交的哈希值、作者、日期、提交信息等元数据。
- 提交中修改的文件及其具体的变更(即显示
diff
)
- 常见用法:
- 查看某个特定提交的详细内容
git show <commit_id>
- 仅查看提交的文件修改(不包括提交信息等元数据)
git show --name-only <commit_id>
- 查看提交的改动统计
git show --stat <commit_id>
- 查看某个特定提交的详细内容
- 适用场景: 当你已经知道某个提交的哈希值,并且想查看该提交的详细内容(包括哪些文件被修改,以及每个文件的变更)。
- 示例:
# 这将展示提交 8a3cdef3e8c58b1cbe3d4f46b0c8ed6e0e63d3d5 的详细信息,包括文件变更和具体差异。git show 8a3cdef3e8c58b1cbe3d4f46b0c8ed6e0e63d3d5
git diff
- 用途: 用于显示当前工作区(工作目录)与暂存区之间、暂存区与当前分支的最新提交之间的差异,或者显示两个提交之间的差异。常用于查看未提交的更改。
- 输出内容: 显示差异(diff),即哪些行发生了变动,+ 表示新增,- 表示删除。
- 常见用法:
- 查看工作目录与暂存区之间的差异(未暂存的更改)
git diff
- 查看暂存区与最新提交之间的差异
git diff --cached
- 查看两个特定提交之间的差异
git diff <commit_id_1> <commit_id_2>
- 查看某个提交与当前工作区之间的差异
git diff <commit_id>
- 查看工作目录与暂存区之间的差异(未暂存的更改)
- 适用场景: 当你想查看当前工作目录、暂存区或两个提交之间的差异时。
- 示例:
# 这将显示当前工作目录与最新提交(HEAD)之间的差异,展示哪些行在本地还没有提交。git diff HEAD
区别总结
git show
git diff
git show
是查看某个提交的详细信息,包括元数据和文件差异。git diff
更关注查看未提交的更改,或查看两个提交之间的差异。
submodule
在 Git
中,子仓库(Submodule
)是一种在一个 Git
仓库中嵌套另一个 Git
仓库的机制,适用于需要将一个项目的某些部分独立管理的场景。子仓库通常被用来管理项目的依赖关系或共享代码库。
什么是子仓库?
子仓库是一个 Git
仓库,作为另一个 Git
仓库(称为主仓库)的子目录存在。每个子仓库都维护自己独立的版本历史和分支,并被主仓库引用为一个特定的提交(类似于快照)。
常用操作
1.添加子仓库
git submodule add <子仓库地址> <路径># 例如git submodule add https://github.com/example/library.git libs/library
是子仓库的远程地址。
是子仓库在主仓库中的存放目录。
执行后会:
- 在主仓库目录下创建一个指向子仓库的文件夹。
- 在
.gitmodules
文件中记录子仓库信息。
2. 初始化子仓库
当从其他开发者处克隆包含子仓库的主仓库时,子仓库不会自动初始化。需要以下步骤
git submodule initgit submodule update
git submodule init
:根据.gitmodules
文件注册子仓库信息。git submodule update
:下载子仓库的代码并检出到指定版本。
3. 更新子仓库
当子仓库有新提交时,可以拉取最新代码
cd <子仓库路径>git pull origin <分支名>
4. 删除子仓库
如果需要从主仓库中移除子仓库,可以按以下步骤操作:
- 删除子仓库的引用和文件:
git submodule deinit -f <子仓库路径>rm -rf .git/modules/<子仓库路径>rm -rf <子仓库路径>
- 从 .gitmodules 文件和 .git/config 文件中删除相关配置。
.gitmodules 文件详解
主仓库会通过 .gitmodules
文件记录子仓库信息。文件内容示例:
[submodule \"libs/library\"] path = libs/library url = https://github.com/example/library.git
path
指定子仓库存放路径。url
指定子仓库的远程地址。
常见问题
子仓库未初始化如何解决?
# --recursive 参数会递归初始化所有嵌套子模块。git submodule update --init --recursive
取消子仓库在主仓库中的未追踪中展示
修改 .gitmodules 文件中的配置
在 .gitmodules
中,可以为子模块设置 ignore
属性,让 Git 忽略子仓库的变动。步骤如下:
- 编辑
.gitmodules
文件:git config -f .gitmodules submodule.<子模块路径>.ignore all
或直接手动修改
.gitmodules
文件,添加以下内容:[submodule \"子模块路径\"] path = 子模块路径 url = 子模块的远程地址 ignore = all
- 更新
Git
配置git submodule update --init --recursivegit add .gitmodulesgit commit -m \"配置子模块忽略变动\"
问题记录
Gitee exceeds quota 100MB
你推送的单个文件超过了 Gitee 的 100MB 限制(免费用户限制单个文件不能超过100MB)
你可以运行以下命令查看 Git 历史中有哪些大文件:
git rev-list --objects --all | sort -k 2 > allfiles.txt
然后查看 allfiles.txt,用文本编辑器打开,找出大于 100MB 的文件。