Git是一个分布式版本控制系统,广泛用于软件开发中。以下是Git的常用命令、功能、作用以及一些使用案例的详细介绍。
Git 基本命令
配置
- git config: 配置用户信息,如用户名和电子邮件。
bash
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
1. git init
-
功能: 初始化一个新的 Git 仓库。
-
作用: 在当前目录下创建一个新的 Git 仓库。
-
案例:
bashgit init
2.git clone
-
功能: 克隆一个远程仓库到本地。
-
作用: 复制远程仓库的所有内容到本地。
-
案例:
bashgit clone https://github.com/user/repo.git
3. git add
-
功能: 添加文件到暂存区。
-
作用: 准备文件以便在下次提交时包含它们。
-
案例:
bashgit add file.txt git add .
4. git commit
-
功能: 提交暂存区的更改。
-
作用: 将暂存区的内容记录到仓库历史中。
-
案例:
bashgit commit -m "Add new feature"
5. git status
-
功能: 显示工作目录和暂存区的状态。
-
作用: 查看哪些文件被修改、哪些文件在暂存区中。
-
案例:
bashgit status
6. git log
-
功能: 显示提交历史。
-
作用: 查看仓库的提交记录。
-
案例:
bashgit log
7. git diff
-
功能: 显示文件的更改。
-
作用: 查看工作目录或暂存区的更改。
-
案例:
bashgit diff git diff --staged
8. git branch
-
功能: 管理分支。
-
作用: 创建、列出、删除分支。
-
案例:
bashgit branch # 列出分支 git branch new-feature # 新建一个分支 git branch -d new-feature # 删除一个分支;这将删除new-feature分支。注意,您不能删除当前所在的分支。 git branch -D new-feature # 强制删除: 如果分支未合并,使用-D选项强制删除:
9. git checkout
-
功能: 切换分支或恢复工作树文件。
-
作用: 切换到指定分支或恢复文件。
-
基本概念:
-
案例:
bashgit checkout main 或 git switch <branch-name> #切换分支 git checkout -b <branch-name> 或 git switch -c <branch-name> # 创建一个新的分支并立即切换到该分支。
10. git merge
-
功能: 合并分支。
-
作用: 将另一个分支的更改合并到当前分支。
-
基本概念:
- 当前分支: 您所在的分支,即您在执行 git merge 命令时所在的分支。
- 目标分支: 您希望合并到当前分支的分支。在 git merge new-feature 中,new-feature 是目标分支。
-
合并类型(快进合并):
-
如果当前分支是目标分支的祖先,Git 会简单地将当前分支的指针移动到目标分支的指针上。
-
这种合并不会创建新的合并提交。
-
示例:
bashgit checkout main git merge new-feature
-
结果:main 分支的指针直接移动到 new-feature 的位置。
-
-
三方合并(Three-way Merge):
-
如果当前分支和目标分支有不同的历史记录,Git 会创建一个新的合并提交。
-
这种合并需要解决冲突(如果有)。
-
示例:
bashgit checkout main git merge new-feature
-
结果: 创建一个新的合并提交,包含来自 main 和 new-feature 的更改。
-
-
合并过程
-
- 切换到目标分支:
-
确保您在要合并到的分支上。例如,合并到 main 分支:
bashgit checkout main
-
- 执行合并:
-
使用 git merge 命令合并目标分支:
bashgit merge new-feature
-
解决冲突(如果有):
-
如果合并过程中出现冲突,Git 会提示您解决冲突。
-
打开冲突文件,手动编辑以解决冲突,然后标记为已解决:
bashgit add <conflicted-file>
-
-
完成合并:
-
如果有冲突,解决后执行:
bashgit commit
-
如果没有冲突,Git 会自动完成合并。
-
-
-
合并冲突
-
冲突标记: 在冲突文件中,Git 会使用以下标记来指示冲突区域:
text<<<<<<< HEAD 当前分支的更改 ======= 目标分支的更改 >>>>>>> new-feature
-
解决冲突: 手动编辑文件以选择或合并更改,然后保存文件。
-
-
合并策略
-
--no-ff: 强制创建合并提交,即使可以快进合并。
bashgit merge --no-ff new-feature
-
--squash: 将目标分支的所有更改压缩为一个提交,但不自动创建合并提交。
bashgit merge --squash new-feature
-
-
总结
- git merge 是合并分支的关键命令,支持快进合并和三方合并。
- 合并过程中可能会遇到冲突,需要手动解决。
- 使用不同的合并策略可以控制合并提交的创建方式。
通过理解和使用 git merge,您可以有效地管理分支合并,支持团队协作和代码集成。
11. git pull
-
功能: 从远程仓库获取并合并更改。
-
作用: 更新本地分支以匹配远程分支。
-
案例:
bashgit pull origin 分支名称
-
常见用例
*- 保持分支最新:
-
在开始新工作之前,使用 git pull 确保您的分支是最新的。
-
这有助于减少合并冲突。
-
- 团队协作:
- 在多人协作的项目中,git pull 是保持代码库同步的关键命令。
-
- 自动化脚本:
- 在CI/CD管道中,git pull 常用于获取最新代码以进行构建和测试。
-
总结
- git pull 是一个强大的命令,用于从远程仓库获取和合并更新。
- 它结合了 git fetch 和 git merge 的功能,简化了更新流程。
- 使用 --rebase 和 --ff-only 等选项可以更好地控制合并行为。
- 在使用 git pull 时,注意处理可能的合并冲突,以确保代码库的稳定性。
12. git push
-
功能: 将本地更改推送到远程仓库。
-
作用: 更新远程仓库以匹配本地提交。
-
案例:
bashgit push origin 分支名称
-
常用选项
-
- -u 或 --set-upstream:
-
功能: 设置本地分支与远程分支的跟踪关系。
-
用法:
bashgit push -u origin main
-
说明: 这将本地的 main 分支与远程的 main 分支关联,以后可以直接使用 git push 推送。
-
- --force 或 -f:
-
功能: 强制推送,覆盖远程分支的历史。
-
用法:
bashgit push --force origin main
-
警告: 强制推送会覆盖远程分支的历史,可能导致其他开发者的工作丢失,需谨慎使用。
-
- --all:
-
功能: 推送所有本地分支到远程仓库。
-
用法:
bashgit push --all origin
-
- --tags:
-
功能: 推送所有本地标签到远程仓库。
-
用法:
bashgit push --tags
-
- --delete:
-
功能: 删除远程分支。
-
用法:
bashgit push origin --delete feature-branch
-
说明: 这将删除远程仓库中的 feature-branch 分支。
-
-
推送过程
-
- 准备推送:
- 确保本地分支的更改已提交。
- 确保本地分支与远程分支同步,避免推送冲突。
-
- 执行推送:
- 使用 git push 命令将本地更改推送到远程仓库。
-
- 处理冲突:
- 如果远程仓库有更新,推送可能会被拒绝。需要先拉取最新更改并解决冲突,然后再推送。
-
-
推送策略
- 快速推送: 仅推送本地分支的最新提交。
- 强制推送: 用于重写远程分支历史,需谨慎使用。
- 推送标签: 用于发布版本时推送标签。
-
总结
- git push 是将本地更改推送到远程仓库的关键命令。
- 使用 -u 选项可以简化后续的推送操作。
- 强制推送和删除远程分支需谨慎操作,以免影响其他开发者。
- 在推送前,确保本地分支与远程分支同步,避免冲突。
通过熟练使用 git push,您可以有效地与团队协作,保持代码库的更新和一致性。
13. git remote
-
功能: 管理远程仓库。
-
作用: 添加、查看、删除远程仓库。
-
查看远程仓库
-
命令: git remote
-
功能: 列出所有配置的远程仓库。
-
用法:
bashgit remote
-
查看仓库详细信息:
-
命令: git remote -v
-
功能: 显示远程仓库的详细信息,包括URL。
-
用法:
bashgit remote -v
-
-
-
添加远程仓库
-
命令: git remote add
-
功能: 添加一个新的远程仓库。
-
用法:
bashgit remote add origin https://github.com/user/repo.git
-
说明: 这将添加一个名为 origin 的远程仓库,指向指定的URL。
-
-
修改远程仓库
-
命令: git remote set-url
-
功能: 修改现有远程仓库的URL。
-
用法:
bashgit remote set-url origin https://github.com/user/new-repo.git
-
说明: 这将更新 origin 远程仓库的URL。
-
-
删除远程仓库
-
命令: git remote remove
-
功能: 删除一个远程仓库。
-
用法:
bashgit remote remove origin
-
说明: 这将删除名为 origin 的远程仓库。
-
-
重命名远程仓库
-
命令: git remote rename
-
功能: 重命名一个远程仓库。
-
用法:
bashgit remote rename origin upstream
-
说明: 这将把 origin 远程仓库重命名为 upstream。
-
-
使用场景
- 多远程仓库: 在一个项目中,您可能需要从多个远程仓库拉取或推送代码。例如,您可以有一个 origin 作为主远程仓库,还有一个 upstream 作为上游仓库。
- 更改远程URL: 当远程仓库的URL发生变化时,您可以使用 set-url 来更新。
- 清理远程引用: 如果某个远程仓库不再使用,您可以将其删除以保持配置的整洁。
-
总结
- git remote 是管理远程仓库的关键命令,支持查看、添加、修改、删除和重命名远程仓库。
- 使用 -v 选项可以查看远程仓库的详细信息。
- 通过管理远程仓库,您可以更好地协作和同步代码。
熟练使用 git remote 命令可以帮助您有效地管理和操作多个远程仓库,支持复杂的协作开发流程。
14. git reset
git reset 是一个强大的 Git 命令,用于撤销更改。它可以影响工作目录、暂存区和提交历史。以下是 git reset 的详细讲解,包括其选项、功能和使用案例。
-
功能: 重置当前分支的HEAD。
-
作用: 取消暂存或提交的更改。
-
基本用法
bashgit reset [<mode>] [<commit>]
-
: 指定重置的模式,常用的有 --soft、--mixed 和 --hard。
-
: 指定要重置到的提交(commit),可以是提交哈希、分支名等。
-
模式详解
- --soft
-
功能: 仅重置HEAD指针到指定的提交,不影响暂存区和工作目录。
-
作用: 保留所有更改在暂存区中,适合需要重新提交的场景。
-
用法:
bashgit reset --soft HEAD~1
-
案例: 撤销最近一次提交,但保留更改以便重新提交。
-
- --mixed (默认模式)
-
功能: 重置HEAD指针和暂存区到指定的提交,不影响工作目录。
-
作用: 暂存区的更改被撤销,但工作目录的更改保留。
-
用法:
bashgit reset --mixed HEAD~1
-
案例: 撤销最近一次提交,并将更改移出暂存区。
-
- --hard
-
功能: 重置HEAD指针、暂存区和工作目录到指定的提交。
-
作用: 所有更改被丢弃,工作目录恢复到指定提交的状态。
-
用法:
bashgit reset --hard HEAD~1
-
案例: 完全撤销最近一次提交及其更改,恢复到之前的状态。
-
- --soft
-
其他选项
-
--merge
-
功能: 保留未合并的更改,重置HEAD和暂存区。
-
用法:
bashgit reset --merge
-
-
--keep
-
功能: 保留未提交的更改,重置HEAD和暂存区。
-
用法:
bashgit reset --keep
-
-
-
使用场景
- 撤销错误提交: 使用 --soft 或 --mixed 模式撤销错误提交,保留更改以便重新提交。
- 清理暂存区: 使用 --mixed 模式清理暂存区,将更改移回工作目录。
- 恢复到特定状态: 使用 --hard 模式恢复到特定提交的状态,丢弃所有更改。
-
注意事项
- 数据丢失: 使用 --hard 模式会丢失所有未提交的更改,需谨慎使用。
- 不可逆操作: git reset 的某些操作不可逆,特别是 --hard 模式。
-
总结
git reset 是一个多功能命令,用于撤销更改和重置仓库状态。通过选择合适的模式,您可以灵活地管理提交历史和工作目录。使用时需谨慎,特别是在涉及数据丢失的操作中。
15. git stash
- 功能: 暂存未提交的更改。
- 作用: 保存当前工作进度以便稍后恢复。
- 案例:
bash
git stash # 说明: 这会将所有未提交的更改(包括已暂存和未暂存的)保存到一个栈中,并将工作目录恢复到上次提交的状态。
git stash list # 说明: 每个存储的更改都有一个唯一的标识符(如 stash@{0}),您可以使用这些标识符来引用特定的存储。
git stash apply # 说明: 这会将最近一次存储的更改应用到当前工作目录,但不会从栈中删除该存储。
git stash pop # 说明: 这会将最近一次存储的更改应用到当前工作目录,并从栈中删除该存储。
git stash apply stash@{n} # 说明: 这会将指定的存储(如 stash@{n})应用到当前工作目录。
git stash drop # 说明: 这会从栈中删除最近一次存储的更改。
git stash drop stash@{1} # 说明: 这会从栈中删除指定的存储(如 stash@{1})。
git stash clear # 说明: 这会删除所有存储的更改。
git stash save "WIP: working on feature X" # 说明: 这会将当前更改保存到栈中,并附加一条描述性消息。
git stash -u # 说明: 这会将未跟踪的文件(即未被 git add 添加的文件)也一起存储。
git stash -a 或 git stash --all # 说明: 这会将所有未提交的更改,包括未跟踪和被 .gitignore 忽略的文件,存储到栈中。
- 总结
git stash 是一个强大的工具,帮助开发者在不想提交未完成的更改时,临时保存工作进度。它允许您在不同的分支之间切换,或在不影响当前工作的情况下进行其他操作。通过熟练使用 git stash,您可以更灵活地管理工作目录中的更改。
16. 子模块管理
Git子模块是Git仓库中的一个功能,允许您将一个Git仓库嵌入到另一个Git仓库中。这对于需要在一个项目中引用其他项目的场景非常有用,比如使用第三方库或共享代码库。以下是关于Git子模块管理的详细讲解:
-
子模块的基本概念
- 子模块: 一个Git仓库可以作为另一个Git仓库的子模块。子模块保留了自己的版本历史和独立性。
- 用途: 适用于需要在多个项目中共享代码库的场景,或者需要在项目中包含外部库而不直接复制代码的情况。
-
添加子模块
-
命令: git submodule add
-
功能: 将一个外部Git仓库添加为当前仓库的子模块。
-
用法:
bashgit submodule add -b master https://bitbucket.org/user/other_repo.git libs
-
说明:
- -b master 指定要使用的分支(例如master)。
- https://bitbucket.org/user/other_repo.git 是子模块的仓库URL。
- libs 是子模块在当前仓库中的目录名称。
-
-
初始化和更新子模块
-
命令: git submodule update --init --recursive
-
功能: 初始化和更新子模块。
-
用法:
bashgit submodule update --init --recursive
-
说明:
- --init 初始化子模块。
- --recursive 递归地初始化和更新子模块中的子模块。
-
-
克隆包含子模块的仓库
-
命令: git clone --recurse-submodules
-
功能: 克隆一个包含子模块的仓库,并同时克隆所有子模块。
-
用法:
bashgit clone --recurse-submodules https://github.com/user/repo.git
-
说明: 使用--recurse-submodules选项确保在克隆主仓库时也克隆所有子模块。
-
-
更新子模块
-
命令: git submodule update --remote
-
功能: 更新子模块到其远程仓库的最新提交。
-
用法:
bashgit submodule update --remote
-
说明: 这将更新子模块到其指定分支的最新提交。
-
-
删除子模块
-
步骤1:
-
编辑.gitmodules文件:
-
打开项目根目录下的.gitmodules文件,找到与子模块相关的条目并删除。
-
例如,如果子模块位于libs/other_repo,则删除类似以下内容的条目:
text[submodule "libs/other_repo"] path = libs/other_repo url = https://bitbucket.org/user/other_repo.git
-
-
编辑.git/config文件:
-
打开项目根目录下的.git/config文件,找到与子模块相关的条目并删除。
-
例如,删除类似以下内容的条目:
text[submodule "libs/other_repo"] url = https://bitbucket.org/user/other_repo.git
-
-
-
步骤2: 删除子模块的缓存
- 从Git缓存中删除子模块:
-
使用git rm命令从Git缓存中删除子模块。
-
例如:
bashgit rm --cached libs/other_repo
-
- 从Git缓存中删除子模块:
-
步骤3: 删除子模块的文件
- 删除子模块的文件夹:
-
手动删除子模块的文件夹。
-
例如:
bashrm -rf libs/other_repo
-
- 删除子模块的文件夹:
-
步骤4: 提交更改
- 提交删除子模块的更改:
-
提交对.gitmodules、.git/config和子模块文件夹的更改。
-
例如:
bashgit add .gitmodules git add .git/config git commit -m "Remove submodule libs/other_repo"
-
- 提交删除子模块的更改:
-
步骤5: 清理子模块的引用
-
清理子模块的引用:
-
使用git submodule deinit命令清理子模块的引用。
-
例如:
bashgit submodule deinit -f -- libs/other_repo
-
-
清理子模块的目录:
-
使用git clean命令清理子模块的目录。
-
例如:
bashgit clean -fdx libs/other_repo
-
-
-
总结
删除Git子模块需要手动编辑配置文件、从缓存中删除子模块、删除子模块的文件夹,并提交这些更改。通过这些步骤,您可以完全从项目中移除子模块。确保在执行这些操作之前备份重要数据,以防止意外数据丢失。
-
-
子模块的常见问题
- 版本固定: 子模块指向的是一个特定的提交,而不是分支的最新状态。这意味着在更新子模块时,您需要手动更新到新的提交。
- 独立性: 子模块是独立的Git仓库,您需要单独提交和推送子模块的更改。
- 复杂性: 子模块增加了项目的复杂性,特别是在处理多个子模块或嵌套子模块时。
-
总结
Git子模块是一个强大的工具,适用于需要在项目中引用其他Git仓库的场景。通过子模块,您可以保持代码库的独立性和版本控制的精确性。然而,子模块也增加了项目的复杂性,需要开发者在使用时仔细管理和维护。
总结
Git 提供了丰富的命令集来管理代码版本、分支、合并、远程仓库和子模块。通过熟练使用这些命令,开发者可以高效地管理项目的代码库,支持团队协作和持续集成。子模块功能特别适合需要在一个项目中引用其他项目的场景。
删除子模块案例(简化版)
在Git中,删除子模块通常需要多个步骤,因为子模块涉及到多个配置文件和缓存。然而,您可以通过组合命令来简化这个过程。以下是一个使用单行命令删除子模块的示例:
-
单行命令删除子模块
假设子模块位于路径 libs/other_repo,您可以使用以下命令:
bashgit submodule deinit -f libs/other_repo && \ rm -rf .git/modules/libs/other_repo && \ git rm -f libs/other_repo
- git submodule deinit -f libs/other_repo:
- 这一步将子模块从Git的配置中取消初始化。-f选项强制执行,即使子模块有未提交的更改。
- 这一步取消初始化子模块,但不会影响工作目录或暂存区。
- rm -rf .git/modules/libs/other_repo:
- 这一步删除子模块在.git/modules目录下的存储信息。这个目录存储了子模块的Git数据。
- 这一步手动删除子模块的Git数据目录。这是一个文件系统操作,不会影响Git的暂存区。
- git rm -f libs/other_repo:
- 这一步从Git的索引中删除子模块,并删除工作目录中的子模块文件夹。-f选项强制删除。
- 这一步从工作目录中删除子模块,并将删除操作自动添加到暂存区。
- git rm的行为类似于git add,它会将删除操作直接记录在暂存区中,因此不需要额外的git add。
- git submodule deinit -f libs/other_repo:
-
提交更改
-
在执行上述命令后,不需要使用git add命令,您只需要提交这些更改以更新仓库的状态:
bashgit commit -m "Remove submodule libs/other_repo"
-
-
注意事项
- 备份数据: 在执行这些命令之前,确保备份任何重要数据,以防止意外丢失。
- 检查路径: 确保路径libs/other_repo是正确的,并且是您想要删除的子模块路径。
- 版本控制: 确保在删除子模块之前,您已经提交了所有其他更改,以避免数据丢失。
通过这种方式,您可以使用一条命令来删除子模块,简化了手动编辑配置文件和缓存的过程。
添加一个子模块案例
-
添加子模块:
bashgit submodule add https://soddsssa.de.osss.com:5559/pjw3/bupoit_uaity.git bopui_quality 或者 git submodule add -b main https://soddsssa.de.osss.com:5559/pjw3/bupoit_uaity.git bopui_quality
-
进入子模块目录并检出特定提交:
bashcd bopui_quality git checkout 47gd07aed60a
-
返回主项目目录并更新子模块引用:
bashcd .. git add built-in_quality git commit -m "Set submodule to specific commit 47ed07ae60a"
- 总结
- -b参数: 通常用于指定分支或标签,但可以通过手动操作将子模块指向特定的提交ID。
- 特定提交ID: 通过手动检出和更新子模块引用,可以将子模块固定在特定的提交状态。
使用-b和手动检出指定提交有什么区别
这两种方式用于添加Git子模块,但它们的行为和结果有所不同。以下是详细的区别和解释:
-
使用 -b 参数
bashgit submodule add -b main https://soddsssa.de.osss.com:5559/pjw3/bupoit_uaity.git bopui_quality
- 行为: 这条命令将子模块添加到当前仓库,并将子模块初始化到指定的分支(在此例中为main)。
- 结果: 子模块会被克隆到bopui_quality目录,并检出main分支的最新提交。
- 更新: 当您运行git submodule update --remote时,子模块会更新到main分支的最新提交。
-
手动检出特定提交
bashgit submodule add https://soddsssa.de.osss.com:5559/pjw3/bupoit_uaity.git bopui_quality cd bopui_quality git checkout 47gd07aed60a
- 行为: 这组命令首先将子模块添加到当前仓库,默认情况下会检出子模块的默认分支(通常是main或master)。
- 结果: 然后,您手动进入子模块目录并检出特定的提交47gd07aed60a。
- 更新: 子模块被固定在特定的提交上,除非手动更改,否则不会自动更新到分支的最新提交。
- 区别总结
- 分支 vs. 提交:
- 使用-b 参数,子模块会跟随指定分支的最新提交。
- 手动检出特定提交,子模块被固定在该提交,不会自动更新。
- 更新行为:
- 使用-b 的子模块可以通过git submodule update --remote来更新到分支的最新提交。
- 手动检出的特定提交需要手动更新到新的提交或分支。
- 使用场景:
- 如果您希望子模块始终保持在某个分支的最新状态,使用-b 是更好的选择。
- 如果您需要子模块保持在特定的提交(例如,经过验证的稳定版本),则手动检出特定提交更合适。
- 分支 vs. 提交:
- 总结
选择哪种方式取决于您的需求:如果您需要子模块跟随分支的最新变化,使用-b ;如果您需要子模块固定在特定的提交上,手动检出该提交。
大概总结了git常用的一些命令, 欢迎大家指出问题!!!