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