Git的认识和使用



前言

Git作为现代软件开发中不可或缺的版本控制工具,已经广泛应用于各种规模的项目中。在这篇文章中,将探讨Git的基本概念、以及在不同场景下的应用,和开发中常用的命令

Git 主要分区

工作区(Working Directory)

工作区是指您实际进行代码编辑、文件操作的本地目录。这是您在日常开发中与之交互的文件系统的一部分,包含了项目的源代码、文档、资源文件等所有内容。当您在IDE中打开项目并进行修改时,就是在工作区内进行操作。

暂存区(Staging Area / Index)

暂存区是 Git 中的一个独特概念,它作为工作区与版本库之间的过渡区域。在对工作区中的文件作出更改后,可以使用 git add 命令将这些更改添加到暂存区。暂存区保存了您打算纳入下一次提交的改动快照。暂存区的存在允许开发者有选择地将工作区的改动分批提交,而非一次性提交所有修改。这样可以更精细地控制每次提交的内容,使得提交历史更加清晰和有组织。 本地仓库(Repository) 版本库是 Git 存储项目历史记录和元数据的核心部分。它通常位于项目根目录下的一个名为 .git 的隐藏目录中。

本地仓库(Local Repository)

存储了项目的全部历史提交信息,每个提交对应一个带有唯一SHA-1哈希值的快照。这些提交构成了项目的版本历史树。

总结来说,Git 的分区包括工作区(直接编辑代码的地方)、暂存区(临时存放已准备提交的改动)以及本地仓库。这三个分区共同构成了 Git 的核心工作流程,使得开发者能够高效、灵活地管理项目版本和协作开发。

分支切换

如果在A分支开发,突然要切换到B分支开发。在不提交A分支的代码的前提下,如何安全切换B分支,处理完任务后,又切回A分支开发。

  • 切换到B分支前: 保存当前工作状态: 使用 git stash/git stash save "Switching to B branch temporarily"命令将当前工作区中未提交的改动暂时存储起来。这会将所有未添加到暂存区的改动(包括新增、删除、修改的文件)移出工作区,使工作目录恢复到上一次提交的状态。
  • 切换到B分支: 切换分支: 现在工作区已经干净,可以安全地切换到B分支了:git checkout B,Git(>= 2.23),推荐使用 git switch
  • 在B分支上进行开发完成后,切换回A分支,恢复A分支之前工作区类容:
    使用 git stash apply ,如果希望在应用stash后将其从堆栈中移除,使用git stash pop 命令恢复之前保存的工作状态。如果存在多个stash,可以指定stash编号(如 stash@{1})来恢复特定的一个:git stash apply/pop stash@{1}。使用git stash list查看所有的stash。可以使用git stash show/drop stash@{1}查看或者删除指定stash。

回退代码

git reset 和 git revert 都是用来撤销或回滚 Git 中的提交,但它们的工作方式和适用场景有所不同

git reset

作用与原理: git reset 主要用于调整当前分支的 HEAD 指针位置,以及与之关联的暂存区(索引)和工作目录的内容。它可以将 HEAD 移动到指定的提交,并可选地更新暂存区和工作目录,使其与所选提交一致。
命令形式: git reset [mode] [commit]
mode 可以是 --soft、–mixed(默认)、–hard 或 --merge,它们决定了 HEAD 移动后如何处理暂存区和工作目录。

–soft:仅移动 HEAD,不改变暂存区和工作目录。已提交的改动会被保存在工作目录中,等待重新提交。

–mixed(默认):移动 HEAD 并清空暂存区,使之与所选提交的索引状态一致,但工作目录内容不变。已提交的改动变为未暂存状态,需要手动 git add 再提交。

–hard:移动 HEAD 并重置暂存区和工作目录,使之与所选提交完全一致。已提交的改动会被丢弃,无法找回。

–merge:移动 HEAD 并尝试将所选提交与当前分支合并,保留冲突需要手动解决。

适用场景:
私有或未推送的提交:在本地工作分支上撤销未公开的提交,尤其是当错误提交尚未推送至远程仓库时。
清理工作区:当需要放弃所有未提交的改动时,可以使用 git reset --hard 来恢复到最近的提交状态。
重排提交历史:通过交互式重置 (git reset --interactive) 来重新组织提交历史,如拆分或合并提交。
回滚到目标提交:git reset --hard commit_hash

风险:
git reset --hard 会永久丢弃未推送的提交和工作目录中的未提交改动,使用时需谨慎。若已推送的提交被 git reset 后覆盖,可能导致远程仓库与本地分支历史不一致,需要额外的 git push --force 操作,这可能影响其他协作者。

git revert

作用与原理: git revert 通过创建一个新的反向补丁提交来撤销指定提交的影响。它不会修改提交历史,而是引入一个新的提交,该提交的效果是抵消指定提交所做的更改。
命令形式: git revert [commit]

适用场景:
已推送的提交:安全地撤销已公开的、他人可能已经基于其进行工作的提交。由于 git revert 不改变历史,因此不需要担心影响其他协作者的分支。
保持提交历史线性:当需要撤销一个提交但希望保留其作为项目历史的一部分时,使用 git revert 可以在提交历史中清晰地记录撤销操作。

风险:
合并冲突:如果被撤销的提交与后续提交有冲突,git revert 过程可能会产生合并冲突,需要手动解决并完成反向补丁提交。
提交历史增长:git revert 会产生一个新的提交,这会导致提交历史变长。虽然这是为了保持历史完整性,但对于频繁的撤销操作可能会增加历史复杂度。

总结:git reset 适用于撤销本地未推送的提交,并可以直接修改工作目录和暂存区状态。它能改变提交历史,操作需谨慎,特别是当涉及已推送的提交时。
git revert 适用于撤销任何已公开的提交,即提交远程仓库的代码,通过创建一个新的反向提交来抵消原有提交的影响,不改变历史,因此更为安全,但可能导致合并冲突并增加历史长度。但撤销的内容不会保存在工作区,同时每次只能revert一次提交。无论采用哪种方式,在回滚操作前都有必要备份原分支代码。

后续处理: 在当前分支(已回滚到目标提交)上,您可以继续进行所需的开发工作。如果需要将原分支上的部分内容合并回当前分支,可以使用 git cherry-pick 命令挑选特定提交,或者使用 git merge 合并整个分支。根据实际情况决定何时以及如何合并这些内容。

查看提交记录

找到目标提交的哈希值:git log --oneline --decorate

版本的简单表示

HEAD 表示当前版本
HEAD^ 上一个版本
HEAD^^ 上上一个版本
HEAD^^^ 上上上一个版本

get merge 和 git cherry-pick的区别

git merge

用于将指定分支的所有提交合并到当前分支。它会寻找两个分支(当前分支与指定分支)的最近共同祖先,然后将这两个分支自共同祖先以来的改动合并到一起,形成一个新的合并提交。

适用场景:
功能集成:当一个功能分支开发完毕,需要将其所有改动合并到主分支或其他目标分支时。
长期合作:在持续集成或长期协作的项目中,定期或按需将不同开发者的分支合并到共享分支(如 main 或 develop)。

特点:
合并提交:生成一个新的合并提交,该提交有两个或更多父提交,代表了两个分支的历史合并。
可能引发冲突:如果两个分支对同一文件的相同区域进行了不同的修改,git merge 会标记出冲突,需要手动解决后才能完成合并。
保留完整历史:合并后,所有参与分支的提交历史都被保留,形成一个完整的线性或非线性历史。

git cherry-pick

用于将指定分支上的单个提交(或一系列明确指定的提交)复制到当前分支,仿佛这些提交原本就在当前分支上一样。它会将选定提交的改动应用于当前分支,并创建一个与原提交具有相同内容的新提交。

适用场景:
独立修复移植:从一个分支中选取特定的 bug 修复提交,应用到其他分支(如将稳定分支的修复移植到开发分支)。
特性拣选:从功能分支中挑选个别提交(如特定优化或小功能),合并到主分支,而不合并整个功能分支。
紧急补丁:在发布周期中,快速将某个提交应用到已发布的分支,制作紧急补丁。

特点:
单个提交复制:只复制指定的提交,不涉及该提交之外的其他历史。
独立的新提交:在当前分支上生成一个与原提交内容相同但具有新SHA-1哈希的新提交。
也可能引发冲突:如果所选提交的改动与当前分支已有内容冲突,git cherry-pick 也会标记出冲突,需要手动解决。
历史非线性增长:每次 cherry-pick 都会增加一个新提交,使得历史呈现非线性发展。

总之,git merge 是将整个分支的全部提交历史合并到当前分支,形成一个合并提交,保留完整历史,适用于功能集成或长期协作。 git cherry-pick 是选取并复制特定提交到当前分支,生成新的独立提交,适用于移植特定修复、拣选特性或制作紧急补丁,适用于少量提交。最好每次只选择一个提交cherry-pick, 因为同时选择多个,当遇到冲突的时候会停止后续合并。

丢弃工作区内容

git checkout .

这条命令会将工作区的所有文件恢复到与最近一次提交(HEAD)相同的版本。注意: 这将丢失所有未暂存的更改,但不会影响已暂存的更改

git restore --worktree --source=HEAD .

这条命令的作用与 git checkout . 相同,但使用了更现代且明确的 git restore 命令,它专门用于恢复工作区或暂存区的内容。–worktree 参数指定恢复工作区,–source=HEAD 指定恢复到最近一次提交的状态。

git reset --hard

这条命令会将 HEAD、暂存区和工作区都重置到最近一次提交的状态,即丢弃所有未提交的更改,无论它们是否已被暂存。

其他命令

  • 重置凭证:
    git config --global --unset credential.helper

  • 存储登陆凭证
    git config --global credential.helper store 这会将凭证信息以明文形式存储在磁盘上,适用于所有Git仓库
    git config --global credential.helper manager。这会将凭证信息存储在Windows Credential Store中,加密存储(windows)

  • 设置用户
    git config --global user.name “Your Name”
    git config --global user.email “youremail@example.com”

  • 添加远程仓库
    git remote add origin <remote_repo_url>

  • 推送
    git push [remote_repo_name] [local_branch_name]:[remote_branch_name]
    remote_repo_name:远程仓库的名称,默认为 origin。
    local_branch_name:要推送的本地分支名称。
    remote_branch_name:要推送到的远程分支名称。如果省略此参数,Git 会尝试推送到同名的远程分支。

  • 拉取
    git pull [remote_repo_name] [branch_name]
    remote_repo_name:远程仓库的名称,默认为 origin。
    branch_name:要拉取的分支名称。

  • git push -u origin master:
    将本地 master 分支的更改推送到名为 origin 的远程仓库的 master 分支。
    设置本地 master 分支的上游跟踪关系为远程仓库 origin 的 master 分支。这意味着在以后的 git pull 和 git push 操作中,可以简单地使用 git pull 和 git push 而不需要指定远程仓库和分支名称。
    例如,在设置了上游跟踪关系后,可以使用以下命令来拉取和推送更改:
    git pull # 从远程 origin/master 分支拉取更新并合并到本地 master 分支
    git push # 将本地 master 分支的更改推送到远程 origin/master 分支

  • 强制推送
    git push -f

愿你我都能在各自的领域里不断成长,勇敢追求梦想,同时也保持对世界的好奇与善意。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值