config
1. 临时修改用户名和邮箱
如果只需要修改当前仓库的提交者信息,可以使用以下命令:
git config user.name "新用户名"
git config user.email "新邮箱地址"
查看配置:
git config user.name
git config user.email
注意:此修改仅对当前仓库有效,不会影响全局配置或其他仓库。
2. 全局修改用户名和邮箱
如果希望更改所有仓库的默认用户名和邮箱,可以使用全局配置:
git config --global user.name "新用户名"
git config --global user.email "新邮箱地址"
查看全局配置:
git config --global user.name
git 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 <new-url> |
添加远程地址 | git remote add <name> <new-url> |
删除远程地址 | git remote remove <name> |
reset
在 Git 中,如果你已经执行了 git add,将文件的更改暂存到索引区,但又想丢弃这些修改,可以通过以下步骤实现
1. 丢弃已暂存的修改
git reset HEAD <file>
或者丢弃所有已暂存的文件
git reset HEAD
作用:
git reset HEAD <file>
会将指定文件从暂存区移回工作区,修改仍然保留在工作区中,但不会再被标记为已暂存。
示例:git reset HEAD myfile.txt
myfile.txt
的修改移出暂存区
2. 丢弃工作区的修改
在执行完
git reset HEAD
后,如果还想丢弃工作区的更改,可以使用以下命令
git checkout -- <file>
或者丢弃所有文件的更改
git checkout -- .
作用:
git checkout -- <file>
会将文件恢复到上一次提交时的状态,丢弃工作区中的修改
3. 一步完成(同时丢弃暂存区和工作区的修改)
如果想直接同时丢弃暂存区和工作区的所有修改,可以使用以下命令
git reset --hard HEAD
作用:
- 此命令将工作区和暂存区重置到最后一次提交的状态,所有未提交的更改都会被丢弃。
- ⚠️ 注意:此命令会直接丢弃所有未提交的修改,不可恢复,操作前请确认没有重要内容。
总结
场景 | 操作 |
---|---|
仅取消暂存区的修改 | git reset HEAD <file> |
取消暂存区修改并恢复文件内容 | git reset HEAD <file> → git checkout -- <file> |
直接丢弃所有已暂存和未暂存的修改 | git reset --hard HEAD |
branch
在 Git 中,分支操作是项目开发中非常常见的任务。以下是关于分支操作的常用命令及详细说明。
1. 查看分支
# 查看本地分支
git branch
# 查看远程分支
git branch -r
# 查看本地和远程分支
git branch -a
2. 创建分支
# 创建分支
git branch <branch_name>
# 创建新分支并且切换到该分支
git checkout -b <branch_name>
3. 切换分支
# 切换到指定分支
git checkout <branch_name>
# 指定提交切换分支
git checkout <branch_name> <commit_hash>
4. 删除分支
# 删除本地分支(只适用于已合并的分支)
git branch -d <branch_name>
# 强制删除本地分支 (未合并的也会被删除)
git branch -D <branch_name>
# 删除远程分支
git push origin --delete <branch_name>
5. 合并分支
# 将指定分支合并到当前分支
git merge <branch_name>
合并冲突处理:
- Git 会提示冲突文件。
- 编辑冲突文件,解决冲突。
- 将修改后的文件标记为解决:
git add <file>
- 完成合并
git commit -m <desc>
6. 推送分支
git push origin <branch_name>
7. 重命名分支
# 重命名当前分支
git branch -m <new_branch_name>
# 重命名指定分支
git branch -m <old_branch_name> <new_branch_name>
8. 分支比较
git diff <branch_1> <branch_2>
9. 分支管理常见流程
开发新功能
- 创建新分支:
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-feature git push origin --delete feature/new-feature
总结
操作 | 命令 |
---|---|
查看分支 | git branch |
创建分支 | git branch <branch_name> |
切换分支 | git switch <branch_name> |
删除分支 | git branch -d <branch_name> |
合并分支 | git merge <branch_name> |
推送分支 | git push origin <branch_name> |
跟踪分支 | git branch --set-upstream-to=origin/<branch_name> |
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 -> C
git switch main
git merge feature
# 合并后:
# main: A -> B -> C
特点:
- 不会生成额外的合并提交。
- 合并历史简单清晰,但不适合需要保留分支开发历史的情况。
3.2 三方合并 (3-Way Merge)
- 条件:如果当前分支和目标分支都有各自的提交记录(有分叉历史)。
- 结果:创建一个新的合并提交,记录两个分支的历史。
示例:
# 假设分支状态如下:
# main: A -> B
# feature: A -> C
git switch main
git merge feature
# 合并后:
# main: A -> B -> D (merge commit)
# ↘ C
特点:
- 生成一个合并提交,记录了两个分支的提交历史。
- 更适合复杂的分支开发场景。
4. 常用选项
git merge
支持多种选项来满足不同场景的需求:
4.1 --squash
- 将另一个分支的所有提交压缩为一个提交,然后合并到当前分支。
- 常用于临时分支开发,将多个提交压缩成一个干净的提交。
示例:
git merge --squash feature
git 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.txt
git add file.txt
git commit -m "Make some changes"
# 切回主线分支合并
git switch main
git merge dev
# 检测历史
git log --oneline --graph
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>
- <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.txt
git commit -m "Remove file.txt"
1.2 只从暂存区移除文件,保留本地文件
# 文件从 暂存区 移除,但仍保留在本地工作区中
# 通常用于将文件从版本控制中忽略(例如文件已错误地加入版本控制)
git rm --cached <file>
# 示例
git rm --cached config.json
git 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 .gitignore git commit -m "Ignore file.txt"
总结
# 删除单个文件
git rm old_file.txt
git commit -m "Remove old_file.txt"
# 删除整个目录
git rm -r old_directory
git commit -m "Remove old_directory"
# 从暂存区移除文件但保留本地文件
git rm --cached config.json
git commit -m "Untrack config.json"
tag
在 Git 中,标签(Tag) 是用来给特定的提交点打上一个易于识别的标记,通常用于标识版本(如 v1.0.0)。
1. 查看现有标签
git tag
2. 创建附注标签
git tag -a <tag_name> -m "<message>"
例如
git tag -a v1.0.0 -m "Release version 1.0.0"
3. 给特定的提交打标签
默认情况下,标签会打在当前的提交上。如果需要给某个特定的提交打标签,可以指定提交的哈希值。
git tag <tag_name> <commit_hash>
例如
git tag v1.0.0 9fceb02
git 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>
log
常用命令
git log --oneline
# 示例
1234567 Initial commit
abcdef1 Add README file
789abcd Fix bug in calculation
#查看从 2024 年 11 月 1 日到 2024 年 11 月 20 日的提交记录。
git log –since=“2024-11-01” –until=“2024-11-20”
查看特定文件的提交记录
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 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 commit
abcdef1 Bob 2024-11-19 Add README file
结合 grep 搜索提交
git log --grep="关键字"
# 示例
git log --grep="fix"
全面查看提交历史
查看所有分支的提交历史(简洁格式 + 图形化 + 全部分支)
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="关键字" |
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 init
git 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 --recursive git add .gitmodules git commit -m "配置子模块忽略变动"