网站空间服务,网站与新媒体建设测评方案,个人做商业网站需要什么,平台设计是做什么文章目录 1、基础操作1_提交命令2_创建分支命令3_切换分支4_分支合并5_其他关键命令 2、高级操作1_查看 HEAD 指向2_分离Head3_查看提交记录的hash值4_相对引用5_撤销变更 3、移动提交记录1_整理提交记录2_交互式 rebase 4、经验之谈1_提交技巧12_提交的技巧23_Git Tags4_Git D… 文章目录 1、基础操作1_提交命令2_创建分支命令3_切换分支4_分支合并5_其他关键命令 2、高级操作1_查看 HEAD 指向2_分离Head3_查看提交记录的hash值4_相对引用5_撤销变更 3、移动提交记录1_整理提交记录2_交互式 rebase 4、经验之谈1_提交技巧12_提交的技巧23_Git Tags4_Git Describe 5、Push Pull —— Git 远程仓库1_git clone2_远程分支3_Git Fetch4_Git Pull5_Git Push6_偏离的工作7_远程服务器拒绝!(Remote Rejected)8_远程跟踪分支9_Git Push 的参数10_Git fetch 的参数11_古怪的source12_Git pull 参数 6、总结 1、基础操作
Git 主要命令本文中的主分支命名采用main而不是传统的master。
1_提交命令
Git 仓库中的提交记录保存的是你的目录下所有文件的快照就像是把整个目录复制然后再粘贴一样但比复制粘贴优雅许多
Git 希望提交记录尽可能地轻量因此在你每次进行提交时它并不会盲目地复制整个目录。条件允许的情况下它会将当前版本与仓库中的上一个版本进行对比并把所有的差异打包到一起作为一个提交记录。
Git 还保存了提交的历史记录。这也是为什么大多数提交记录的上面都有 parent 节点的原因 —— 对于项目组的成员来说维护提交历史对大家都有好处。
git commit2_创建分支命令
Git 的分支也非常轻量。它们只是简单地指向某个提交纪录 —— 仅此而已。所以许多 Git 爱好者传颂早建分支多用分支
这是因为即使创建再多的分支也不会造成储存或内存上的开销并且按逻辑分解工作到不同的分支要比维护那些特别臃肿的分支简单多了。
git branch 分支名 #新版支持 git switch3_切换分支
git checkout 分支名4_分支合并
第一种方法在 Git 中合并两个分支时会产生一个特殊的提交记录它有两个 parent 节点。翻译成自然语言相当于“我要把这两个 parent 节点本身及它们所有的祖先都包含进来。”
# 在 main 分支上对 bugFix合并
git checkout main
git merge bugFix第二种合并分支的方法是实际上就是取出一系列的提交记录“复制” 它们然后在另外一个地方逐个的放下去。 R e b a s e Rebase Rebase 的优势就是可以创造更线性的提交历史这听上去有些难以理解。如果只允许使用 Rebase 的话代码库的提交历史将会变得异常清晰。
# 把 bugFix 分支里的工作直接移到 main 分支上。
# 移动以后会使得两个分支的功能看起来像是按顺序开发但实际上它们是并行开发的。
# 并且原 bugFix 分支上的提交记录依然存在作为副本
git checkout bugFix
git rebash main如果是继承关系的合并Git 只会简单的把父分支的引用向前移动了一下而已。 5_其他关键命令
# 初始化本地Git仓库, 创建新仓库。
git init
# 添加文件到暂存区。
git add
# 查看仓库当前状态。
git status
# 比较文件差异。
git diff
#删除文件。
git rm
#移动或重命名文件。
git mv
#配置Git设置。
git config
#显示分支和提交信息。
git show-branch
#检查仓库完整性。
git fsck
#清理仓库和优化存储。
git gc2、高级操作
在接触 Git 更高级功能之前我们有必要先学习在你项目的提交树上前后移动的几种方法。
1_查看 HEAD 指向
HEAD 是一个对当前所在分支的符号引用 —— 也就是指向你正在其基础上进行工作的提交记录。
HEAD 总是指向当前分支上最近一次提交记录。大多数修改提交树的 Git 命令都是从改变 HEAD 的指向开始的。
HEAD 通常情况下是指向分支名的如 bugFix。在你提交时改变了 bugFix 的状态这一变化通过 HEAD 变得可见。
cat .git/HEAD如果 HEAD 指向的是一个引用还可以查看它的指向 git symbolic-ref HEAD2_分离Head
分离的 HEAD 就是让其指向了某个具体的提交记录而不是分支名。
# 通过哈希值指定提交记录。
git checkout c2hashvalue # 既不是 bugFix也不是main分支而是提交记录3_查看提交记录的hash值
Git 对哈希的处理很智能。其实你只需要提供能够唯一标识提交记录的前几个字符即可。
git log4_相对引用
通过哈希值指定提交记录很不方便所以 Git 引入了相对引用。
使用相对引用的话你就可以从一个易于记忆的地方比如 bugFix 分支或 HEAD开始计算。
使用 ^ 向上移动 1 个提交记录
# main^ 相当于“main 的 parent 节点”。main^^ 是 main 的第二个 parent 节点
git checkout main^
# 也可以将 HEAD 作为相对引用的参照。一直向上移动
git checkout c3
git checkout HEAD^但是如果你想在提交树中向上移动很多步的话敲那么多 ^ 貌似也挺烦人的Git 当然也考虑到了这一点于是又引入了操作符 ~。
该操作符后面可以跟一个数字可选不跟数字时与 ^ 相同向上移动一次。
使用 ~num 向上移动多个提交记录如 ~3
git checkout main~3我使用相对引用最多的就是移动分支。可以直接使用 -f 选项让分支指向另一个提交。例如:
git branch -f main HEAD~3上面的命令会将 main 分支强制指向 HEAD 的第 3 级 parent 提交。
5_撤销变更
在 Git 里撤销变更的方法很多。和提交一样撤销变更由底层部分暂存区的独立文件或者片段和上层部分变更到底是通过哪种方式被撤销的组成。我们里主要关注的是后者。主要有两种方法用来撤销变更
git reset 通过把分支记录回退几个提交记录来实现撤销改动。你可以将这想象成“改写历史”。git reset 向上移动分支原来指向的提交记录就跟从来没有提交过一样。
# 把 main 分支移回到 C1现在我们的本地代码库根本就不知道有 C2 这个提交了。
git reset HEAD~1虽然在你的本地分支中使用 git reset 很方便但是这种“改写历史”的方法对大家一起使用的远程分支是无效的为了撤销更改并分享给别人我们需要使用 git revert。
# 在我们要撤销的C2提交记录后面会多了一个新提交这是因为新提交记录 C2 引入了更改
# 这些更改刚好是用来撤销 C2 这个提交的。也就是说 C2 的状态与 C1 是相同的。revert 之后就可以把你的更改推送到远程仓库与别人分享啦。
git revert HEAD3、移动提交记录
自由修改提交树。
1_整理提交记录
开发人员有时会说“我想要把这个提交放到这里那个提交放到刚才那个提交的后面”而接下来就讲的就是它的实现方式非常清晰、灵活还很生动。
如果你想将一些提交复制到当前所在的位置HEAD下面的话 C h e r r y − p i c k Cherry-pick Cherry−pick 是最直接的方式了。我个人非常喜欢 cherry-pick因为它特别简单。
git cherry-pick 提交号
# git cherry-pick c2 c4我们只需要提交记录 C2 和 C4所以 Git 就将被它们抓过来放到当前分支下了。
c0 - c1 - c5 - c2 - c4(*)| - c2 - c3 - c42_交互式 rebase
当你知道你所需要的提交记录并且还知道这些提交记录的哈希值时用 cherry-pick 再好不过了 —— 没有比这更简单的方式了。
但是如果你不清楚你想要的提交记录的哈希值呢? 幸好 Git 帮你想到了这一点我们可以利用交互式的 rebase —— 如果你想从一系列的提交记录中找到想要的记录这就是最好的方法了。
交互式 rebase 指的是使用带参数 --interactive 的 rebase 命令简写为 -i。
如果你在命令后增加了这个选项Git 会打开一个 UI 界面并列出将要被复制到目标分支的备选提交记录它还会显示每个提交记录的哈希值和提交说明提交说明有助于你理解这个提交进行了哪些更改。
在实际使用时所谓的 UI 窗口一般会在文本编辑器 —— 如 Vim —— 中打开一个文件。
当 rebase UI界面打开时你能做3件事:
调整提交记录的顺序删除你不想要的提交通过切换 pick 的状态来完成合并提交。 它允许你把多个提交记录合并成一个。
会出现一个交互对话框。对提交记录做个排序当然你也可以删除某些提交点击确定看结果Git 严格按照你在对话框中指定的方式进行了复制。
git rebase -i HEAD~44、经验之谈
来看一个在开发中经常会遇到的情况我正在解决某个特别棘手的 Bug为了便于调试而在代码中添加了一些调试命令并向控制台打印了一些信息。
这些调试和打印语句都在它们各自的提交记录里。最后我终于找到了造成这个 Bug 的根本原因解决掉以后觉得沾沾自喜
最后就差把 bugFix 分支里的工作合并回 main 分支了。你可以选择通过 fast-forward 快速合并到 main 分支上但这样的话 main 分支就会包含我这些调试语句了。你肯定不想这样应该还有更好的方式……
实际我们只要让 Git 复制解决问题的那一个提交记录就可以了。跟之前我们在“整理提交记录”中学到的一样我们可以使用
git rebase -i
git cherry-pick来达到目的。
1_提交技巧1
接下来这种情况也是很常见的你之前在 newImage 分支上进行了一次提交然后又基于它创建了 caption 分支然后又提交了一次。
此时你想对某个以前的提交记录进行一些小小的调整。比如设计师想修改一下newImage 中图片的分辨率尽管那个提交记录并不是最新的了。
我们可以通过下面的方法来克服困难
1. 先用 git rebase -i 将提交重新排序, 然后把我们想要修改的提交记录挪到最前
2. 然后用 git commit --amend 来进行一些小修改
3. 接着再用 git rebase -i 来将他们调回原来的顺序
4. 最后我们把 main 移到修改的最前端(用你自己喜欢的方法), 就大功告成啦2_提交的技巧2
正如你在上面所见到的我们可以使用 rebase -i 对提交记录进行重新排序。只要把我们想要的提交记录挪到最前端我们就可以很轻松的用 --amend 修改它然后把它们重新排成我们想要的顺序。
但这样做就唯一的问题就是要进行两次排序而这有可能造成由 rebase 而导致的冲突。所以最好还是使用 git cherry-pick。
3_Git Tags
相信通过前面的学习你已经发现了分支很容易被人为移动并且当有新的提交时它也会移动。分支很容易被改变大部分分支还只是临时的并且还一直在变。
你可能会问了有没有什么可以永远指向某个提交记录的标识呢比如软件发布新的大版本或者是修正一些重要的 Bug 或是增加了某些新特性有没有比分支更好的可以永远指向这些提交的方法呢
当然有了Git 的 tag 就是干这个用的它们可以在某种程度上 —— 因为标签可以被删除后重新在另外一个位置创建同名的标签永久地将某个特定的提交命名为里程碑然后就可以像分支一样引用了。
更难得的是它们并不会随着新的提交而移动。你也不能切换到某个标签上面进行修改提交它就像是提交树上的一个锚点标识了某个特定的位置。
咱们来看看标签到底是什么样。
# 先建立一个标签, 指向提交记录 C1, 表示这是我们 1.0 版本。
git tag v1 c1
# 不能直接在v1 上面做 commit。所以会进到分离 HEAD 的状态
git checkout v14_Git Describe
由于标签在代码库中起着“锚点”的作用Git 还为此专门设计了一个命令用来描述离你最近的锚点也就是标签它就是 git describe
Git Describe 能帮你在提交历史中移动了多次以后找到方向当你用 git bisect一个查找产生 Bug 的提交记录的指令找到某个提交记录时或者是当你坐在你那刚刚度假回来的同事的电脑前时可能会用到这个命令。
git describe 的语法是
git describe refref 可以是任何能被 Git 识别成提交记录的引用如果你没有指定的话Git 会使用你目前所在的位置HEAD。
它输出的结果是这样的
tag_numCommits_ghashtag 表示的是离 ref 最近的标签numCommits 是表示这个 ref 与 tag 相差有多少个提交记录hash 表示的是你所给定的 ref 所表示的提交记录哈希值的前几位。
当 ref 提交记录上有某个标签时则只输出标签名称
c0[v1] - c1 - c3[v2] - c4 (side*)|- c2 (main)
git describe main# 会输出v1_2_gC2git describe side# 会输出v2_1_gC45、Push Pull —— Git 远程仓库
远程仓库并不复杂在如今的云计算盛行的世界很容易把远程仓库想象成一个富有魔力的东西但实际上它们只是你的仓库在另个一台计算机上的拷贝。你可以通过因特网与这台计算机通信 —— 也就是增加或是获取提交记录。
话虽如此远程仓库却有一系列强大的特性
首先也是最重要的的点远程仓库是一个强大的备份。本地仓库也有恢复文件到指定版本的能力但所有的信息都是保存在本地的。有了远程仓库以后即使丢失了本地所有数据你仍可以通过远程仓库拿回你丢失的数据。
还有就是远程让代码社交化了! 既然你的项目被托管到别的地方了你的朋友可以更容易地为你的项目做贡献(或者拉取最新的变更)
现在用网站来对远程仓库进行可视化操作变得越发流行了(像 GitHub)但远程仓库永远是这些工具的顶梁柱因此理解其概念非常的重要!
1_git clone
直到现在本文都聚焦于本地仓库的操作branch、merge、rebase 等等。但我们现在需要学习远程仓库的操作 —— 我们需要一个配置这种环境的命令它就是 git clone。 从技术上来讲git clone 命令在真实的环境下的作用是在本地创建一个远程仓库的拷贝比如从 github.com。
git clone [远程仓库地址]2_远程分支
既然你已经看过 git clone 命令了咱们深入地看一下发生了什么。
你可能注意到的第一个事就是在我们的本地仓库多了一个名为 o/main 的分支这种类型的分支就叫远程分支。由于远程分支的特性导致其拥有一些特殊属性。
远程分支反映了远程仓库(在你上次和它通信时)的状态。这会有助于你理解本地的工作与公共工作的差别 —— 这是你与别人分享工作成果前至关重要的一步.
远程分支有一个特别的属性在你切换到远程分支时自动进入分离 HEAD 状态。Git 这么做是出于不能直接在这些分支上进行操作的原因你必须在别的地方完成你的工作更新了远程分支之后再用远程分享你的工作成果。
为什么有 o/ 你可能想问这些远程分支的前面的 o/ 是什么意思呢好吧远程分支有一个命名规范 —— 它们的格式是:
remote name/branch name因此如果你看到一个名为 o/main 的分支那么这个分支就叫 main远程仓库的名称就是 o。
大多数的开发人员会将它们主要的远程仓库命名为 origin并不是 o。这是因为当你用 git clone 某个仓库时Git 已经帮你把远程仓库的名称设置为 origin 了
不过 origin 还是太长了因此简写成 o 但是要记住当你使用真正的 Git 时你的远程仓库默认为 origin!
#如果切换到远程分支会怎么样呢
git checkout o/main;git commit
#Git 会变成了分离 HEAD 状态, 当添加新的提交时 o/main 也不会更新这里只会本地提交。这是因为 o/main 只有在远程仓库中相应的分支更新了以后才会更新。3_Git Fetch
Git 远程仓库相当的操作实际可以归纳为两点向远程仓库传输数据以及从远程仓库获取数据。既然我们能与远程仓库同步那么就可以分享任何能被 Git 管理的更新因此可以分享代码、文件、想法、情书等等。
接下来我们将学习如何从远程仓库获取数据 —— 命令如其名它就是 git fetch。
你会看到当我们从远程仓库获取数据时远程分支也会更新以反映最新的远程仓库。我们已经提及过这一点了。
# 这里假设我们有一个远程仓库, 它有两个我们本地仓库中没有的提交。
git fetch [远程仓库地址]
# git fetch 后这两次没有的提交记录会被下载到本地。同时远程分支 o/main 也被更新git fetch 完成了仅有的但是很重要的两步:
从远程仓库下载本地仓库中缺失的提交记录。更新远程分支指针(如 o/main)。
git fetch 实际上将本地仓库中的远程分支更新成了远程仓库相应分支最新的状态。
前面说过远程分支反映了远程仓库在你最后一次与它通信时的状态git fetch 就是你与远程仓库通信的方式了希望我说的够明白了你已经了解 git fetch 与远程分支之间的关系了吧。
git fetch 通常通过互联网使用 http:// 或 git:// 协议) 与远程仓库通信。
git fetch 不会做的事
git fetch 并不会改变你本地仓库的状态。它不会更新你的 main 分支也不会修改你磁盘上的文件。
理解这一点很重要因为许多开发人员误以为执行了 git fetch 以后他们本地仓库就与远程仓库同步了。它可能已经将进行这一操作所需的所有数据都下载了下来但是并没有修改你本地的文件。不过有能完成该操作的命令 :D。
所以你可以将 git fetch 的理解为单纯的下载操作。
4_Git Pull
既然我们已经知道了如何用 git fetch 获取远程的数据现在我们学习如何将这些变化更新到我们的工作当中。
其实有很多方法的 —— 当远程分支中有新的提交时你可以像合并本地分支那样来合并远程分支。也就是说就是你可以执行以下命令:
git cherry-pick o/main
git rebase o/main
git merge o/main
## 等等实际上由于先抓取更新再合并到本地分支这个流程很常用因此 Git 提供了一个专门的命令来完成这两个操作。它就是我们要讲的 git pull。
# git fetch; git merge o/main
git pull [远程仓库地址]5_Git Push
OK我们已经学过了如何从远程仓库获取更新并合并到本地的分支当中。这非常棒……但是我如何与大家分享我的成果呢
嗯上传自己分享内容与下载他人的分享刚好相反那与 git pull 相反的命令是什么呢git push
git push 负责将你的变更上传到指定的远程仓库并在远程仓库上合并你的新提交记录。一旦 git push 完成你的朋友们就可以从这个远程仓库下载你分享的成果了
你可以将 git push 想象成发布你成果的命令。它有许多应用技巧稍后我们会了解到但是咱们还是先从基础的开始吧……
注意 —— git push 不带任何参数时的行为与 Git 的一个名为 push.default 的配置有关。它的默认值取决于你正使用的 Git 的版本但是我使用的是 upstream。 这没什么太大的影响但是在你的项目中进行推送之前最好检查一下这个配置。
git push [远程仓库地址]远程仓库接收了最新的提交远程仓库中的 main 分支也被更新到指向 C2 了我们的远程分支 (o/main) 也同样被更新了。所有的分支都同步了
6_偏离的工作
现在我们已经知道了如何从其它地方 pull 提交记录以及如何 push 我们自己的变更。看起来似乎没什么难度但是为何还会让人们如此困惑呢
困难来自于远程库提交历史的偏离。在讨论这个问题的细节前我们先来看一个例子……
假设你周一克隆了一个仓库然后开始研发某个新功能。到周五时你新功能开发测试完毕可以发布了。但是 —— 天啊你的同事这周写了一堆代码还改了许多你的功能中使用的 API这些变动会导致你新开发的功能变得不可用。但是他们已经将那些提交推送到远程仓库了因此你的工作就变成了基于项目旧版的代码与远程仓库最新的代码不匹配了。
这种情况下git push 就不知道该如何操作了。如果你执行 git pushGit 应该让远程仓库回到星期一那天的状态吗还是直接在新代码的基础上添加你的代码亦或由于你的提交已经过时而直接忽略你的提交
因为这情况历史偏离有许多的不确定性Git 是不会允许你 push 变更的。实际上它会强制你先合并远程最新的代码然后才能分享你的工作。
假设此时执行git push则什么都不会改变因为命令失败了git push 失败是因为你最新提交的 C3 基于远程分支中的 C1。而远程仓库中该分支已经更新到 C2 了所以 Git 拒绝了你的推送请求。
那该如何解决这个问题呢很简单你需要做的就是使你的工作基于最新的远程分支。
有许多方法做到这一点呢不过最直接的方法就是通过 rebase 调整你的工作。咱们继续看看怎么 rebase
如果我们在 push 之前做 rebase 呢
git fetch;git rebase o/main;git push我们用 git fetch 更新了本地仓库中的远程分支然后用 r e b a s e rebase rebase 将我们的工作移动到最新的提交记录下最后再用 git push 推送到远程仓库。
还有其它的方法可以在远程仓库变更了以后更新我的工作吗? 当然有我们还可以使用 merge
尽管 git merge 不会移动你的工作它会创建新的合并提交但是它会告诉 Git 你已经合并了远程仓库的所有变更。这是因为远程分支现在是你本地分支的祖先也就是说你的提交已经包含了远程分支的所有变化。
git fetch;git merge o/main;git push我们用 git fetch 更新了本地仓库中的远程分支然后合并了新变更到我们的本地分支为了包含远程仓库的变更最后我们用 git push 把工作推送到远程仓库。
很好但是要敲那么多命令有没有更简单一点的
当然 —— 前面已经介绍过 git pull 就是 fetch 和 merge 的简写类似的 git pull --rebase 就是 fetch 和 rebase 的简写
# 跟之前结果一样,但是命令更短了。
git pull --rebase;git push
# 还可以使用以下常规的,只不过远程和merge一样会产生分叉,不像rebase就一直一条路
git pull;git push在开发社区里有许多关于 merge 与 rebase 的讨论。以下是关于 rebase 的优缺点
优点缺点Rebase 使你的提交树变得很干净所有的提交都在一条线上Rebase 修改了提交树的历史
比如提交 C1 可以被 rebase 到 C3 之后。这看起来 C1 中的工作是在 C3 之后进行的但实际上是在 C3 之前。
一些开发人员喜欢保留提交历史因此更偏爱 merge。而其他人比如我自己可能更喜欢干净的提交树于是偏爱 rebase。仁者见仁智者见智。
7_远程服务器拒绝!(Remote Rejected)
如果你是在一个大的合作团队中工作很可能是main被锁定了需要一些Pull Request流程来合并修改。如果你直接提交 (commit) 到本地main然后试图推送 (push) 修改你将会收到这样类似的信息:
! [远程服务器拒绝] main - main (TF402455: 不允许推送(push)这个分支; 你必须使用pull request来更新这个分支.)为什么会被拒绝?
远程服务器拒绝直接推送 (push) 提交到main因为策略配置要求 pull requests 来提交更新.
你应该按照流程新建一个分支推送 (push) 这个分支并申请pull request但是你忘记并直接提交给了main. 现在你卡住并且无法推送你的更新.
解决办法
新建一个分支feature推送到远程服务器. 然后reset你的main分支和远程服务器保持一致否则下次你pull并且他人的提交和你冲突的时候就会有问题.
# 创建新分支
git branch feature
# 切换到创建的分支
git checkout feature
# 推送到远程服务器
git push
# 由于推送后主分支会自动跟新分支合并, 需要同步和远程一致
git checkout main
git reset o/main
# 开始操作新分支
git checkout feature8_远程跟踪分支
在前面中有件事儿挺神奇的Git 好像知道 main 与 o/main 是相关的。当然这些分支的名字是相似的可能会让你觉得是依此将远程分支 main 和本地的 main 分支进行了关联。这种关联在以下两种情况下可以清楚地得到展示
pull 操作时提交记录会被先下载到 o/main 上之后再合并到本地的 main 分支。隐含的合并目标由这个关联确定的。push 操作时我们把工作从 main 推到远程仓库中的 main 分支(同时会更新远程分支 o/main) 。这个推送的目的地也是由这种关联确定的
直接了当地讲main 和 o/main 的关联关系就是由分支的 “remote tracking” 属性决定的。main 被设定为跟踪 o/main —— 这意味着为 main 分支指定了推送的目的地以及拉取后合并的目标。
你可能想知道 main 分支上这个属性是怎么被设定的你并没有用任何命令指定过这个属性呀好吧当你克隆仓库的时候Git 就自动帮你把这个属性设置好了。
当你克隆时Git 会为远程仓库中的每个分支在本地仓库中创建一个远程分支比如 o/main。然后再创建一个跟踪远程仓库中活动分支的本地分支默认情况下这个本地分支会被命名为 main。
克隆完成后你会得到一个本地分支如果没有这个本地分支的话你的目录就是“空白”的但是可以查看远程仓库中所有的分支如果你好奇心很强的话。这样做对于本地仓库和远程仓库来说都是最佳选择。
这也解释了为什么会在克隆的时候会看到下面的输出
local branch main set to track remote branch o/main我能自己指定这个属性吗
当然可以啦你可以让任意分支跟踪 o/main然后该分支会像 main 分支一样得到隐含的 push 目的地以及 merge 的目标。 这意味着你可以在分支 totallyNotMain 上执行 git push将工作推送到远程仓库的 main 分支上。
有两种方法设置这个属性第一种就是通过远程分支切换到一个新的分支执行:
git checkout -b totallyNotMain o/main就可以创建一个名为 totallyNotMain 的分支它跟踪远程分支 o/main。
另一种设置远程追踪分支的方法就是使用git branch -u 命令执行
git branch -u o/main foo这样 foo 就会跟踪 o/main 了。如果当前就在 foo 分支上还可以省略 foo
git branch -u o/main9_Git Push 的参数
很好! 既然你知道了远程跟踪分支我们可以开始揭开 git push、fetch 和 pull 的神秘面纱了。我们会逐个介绍这几个命令它们在理念上是非常相似的。
首先来看 git push。在远程跟踪中你已经学到了 Git 是通过当前所在分支的属性来确定远程仓库以及要 push 的目的地的。这是未指定参数时的行为我们可以为 push 指定参数语法是
git push remote placeplace 参数是什么意思呢我们稍后会深入其中的细节先看看例子这个命令是:
git push origin main把这个命令翻译过来就是
切到本地仓库中的 “main” 分支获取所有的提交再到远程仓库 “origin” 中找到 “main” 分支将远程仓库中没有的提交记录都添加上去搞定之后告诉我。
我们通过 “place” 参数来告诉 Git 提交记录来自于 main要推送到远程仓库中的 main。它实际就是要同步的两个仓库的位置。
需要注意的是因为我们通过指定参数告诉了 Git 所有它需要的信息所以它就忽略了我们所切换分支的属性
同时如果HEAD处于分离状态不指定 place 参数会提交失败。
place参数详解
还记得之前说的吧当为 git push 指定 place 参数为 main 时我们同时指定了提交记录的来源和去向。
你可能想问 —— 如果来源和去向分支的名称不同呢比如你想把本地的 foo 分支推送到远程仓库中的 bar 分支。
哎很遗憾 Git 做不到…… 开个玩笑别当真当然是可以的啦 Git 拥有超强的灵活性有点过于灵活了
接下来咱们看看是怎么做的……
要同时为源和目的地指定 place 的话只需要用冒号 : 将二者连起来就可以了
git push origin source:destination这个参数实际的值是个 refspec“refspec” 是一个自造的词意思是 Git 能识别的位置比如分支 foo 或者 HEAD~1
一旦你指定了独立的来源和目的地就可以组织出言简意赅的远程操作命令了让我们看看演示
记住source 可以是任何 Git 能识别的位置
git push origin foo^:main这是个令人困惑的命令但是它确实是可以运行的 —— Git 将 foo^ 解析为一个位置上传所有未被包含到远程仓库里 main 分支中的提交记录。
如果你要推送到的目的分支不存在会怎么样呢没问题 Git 会在远程仓库中根据你提供的名称帮你创建这个分支
git push origin main:newBranch很赞吧它是不是很聪明
10_Git fetch 的参数
我们刚学习了 git push 的参数很酷的 place 参数还有用冒号分隔的 refspecssource:destination。 这些参数可以用于 git fetch 吗
你猜中了git fetch 的参数和 git push 极其相似。他们的概念是相同的只是方向相反罢了因为现在你是下载而非上传
place参数 如果你像如下命令这样为 git fetch 设置 的话 git fetch origin fooGit 会到远程仓库的 foo 分支上然后获取所有本地不存在的提交放到本地的 o/foo 上。 你可能会好奇 —— 为何 Git 会将新提交放到 o/foo 而不是放到我本地的 foo 分支呢之前不是说这样的 参数就是同时应用于本地和远程的位置吗 这里需要 Git 做一些特殊处理因为你可能在 foo 分支上的工作还未完成你也不想弄乱它。还记得在 git fetch 里我们讲到的吗 —— 它不会更新你的本地的非远程分支只是下载提交记录这样你就可以对远程分支进行检查或者合并了。 “如果我们指定 source:destination 会发生什么呢” 如果你觉得直接更新本地分支很爽那你就用冒号分隔的 refspec 吧。不过你不能在当前切换的分支上干这个事但是其它分支是可以的。 这里有一点是需要注意的 —— source 现在指的是远程仓库中的位置而 destination 才是要放置提交的本地仓库的位置。它与 git push 刚好相反这是可以讲的通的因为我们在往相反的方向传送数据。 理论上虽然行的通但开发人员很少这么做。我在这里介绍它主要是为了从概念上说明 fetch 和 push 的相似性只是方向相反罢了。 # Git 将 C2 解析成一个 origin 仓库的位置然后将那些提交记录下载到了本地的 bar 分支一个本地分支上。
git fetch origin C2:bar
# 如果执行命令前目标分支不存在跟 git push 一样Git 会在 fetch 前自己创建立本地分支
#如果 git fetch 没有参数它会下载所有的提交记录到各个远程分支……11_古怪的source Git 有两种关于 source 的用法是比较诡异的即你可以在 git push 或 git fetch 时不指定任何 source方法就是仅保留冒号和 destination 部分source 部分留空。 git push origin :side
git fetch origin :bugFix我们分别来看一下这两条命令的作用…… 如果 push 传空值 source 到远程仓库会如何呢它会删除远程仓库中的分支 如果 fetch 空 到本地会在本地创建一个新分支。很神奇吧但无论怎么说这就是 Git 12_Git pull 参数 既然你已经掌握关于 git fetch 和 git push 参数的方方面面了关于 git pull 几乎没有什么可以讲的了 因为 git pull 到头来就是 fetch 后跟 merge 的缩写。你可以理解为用同样的参数执行 git fetch然后再 merge 你所抓取到的提交记录。 还可以和其它更复杂的参数一起使用来看一些例子: 以下命令在 Git 中是等效的: git pull origin foo #相当于git fetch origin foo; git merge o/foo还有… git pull origin bar:bugFix #相当于git fetch origin bar:bugFix; git merge bugFix看到了 ? git pull 实际上就是 fetch merge 的缩写git pull 唯一关注的是提交最终合并到哪里也就是为 git fetch 所提供的 destination 参数 6、总结 希望本文可以更好的帮助你在工作中更加有效的使用Git。 另外附上一张包含常用 Git 命令大全的表格来源Chat不一定完全准确。 命令名称描述用法示例其他相关信息git init初始化一个新的 Git 仓库git init在当前目录创建一个新仓库git clone克隆一个远程仓库到本地git clone https://github.com/user/repo.git可指定目录git clone url directorygit add将文件添加到暂存区git add filename添加所有更改git add .git commit提交暂存区中的更改到仓库git commit -m commit message添加 -a 参数可以跳过暂存区直接提交所有更改git status显示工作目录和暂存区的状态git status简短输出git status -sgit log显示提交历史git log查看某一特定提交git log commitgit diff显示工作目录和暂存区之间的差异git diff比较暂存区和仓库git diff --cachedgit branch列出、创建或删除分支git branch创建新分支git branch new_branchgit checkout切换分支或恢复工作目录文件git checkout branch_name创建并切换新分支git checkout -b new_branchgit merge将指定分支的更改合并到当前分支git merge branch_name解决冲突后需要再次提交git pull从远程仓库拉取更改并合并到当前分支git pull origin branch_name相当于 git fetch git mergegit push将本地分支的更改推送到远程仓库git push origin branch_name强制推送git push -f origin branch_namegit remote管理远程仓库git remote -v查看远程仓库git remote -vgit fetch从远程仓库获取最新的更改但不合并git fetch origin不会影响当前工作目录git tag列出、创建或删除标签git tag创建新标签git tag v1.0git stash临时保存当前工作目录的更改git stash恢复更改git stash popgit reset重置当前 HEAD 到指定的状态git reset --hard HEAD~1软重置git reset --soft HEAD~1git rebase将当前分支的更改移动到另一个分支上git rebase master交互式git rebase -i commitgit cherry-pick将指定的提交应用到当前分支git cherry-pick commit处理冲突后需要解决git revert创建一个新的提交来撤销指定的提交git revert commit不改变历史记录git reflog显示所有引用日志git reflog用于恢复丢失的提交git submodule管理子模块git submodule add url path初始化git submodule initgit config配置 Git 的全局或仓库特定设置git config --global user.name Your Name查看配置git config --listgit blame显示文件的每一行最后修改的提交记录git blame filename显示详细信息git blame -L 1,10 filenamegit gc清理不必要的文件和优化本地仓库git gc自动运行git gc --autogit archive创建一个包含指定提交的归档文件git archive --formatzip HEAD archive.zip支持多种格式tar, zipgit grep在仓库中搜索指定字符串git grep search string搜索特定提交git grep search string commitgit bisect通过二分查找来定位引入错误的提交git bisect start标记坏提交git bisect badgit filter-branch重写 Git 仓库的历史git filter-branch --tree-filter rm -f password.txt HEAD小心使用可能影响历史记录git clean清理未跟踪的文件git clean -f交互式清理git clean -igit rev-parse解析引用名称或其他字符串为提交的 SHA-1 哈希值git rev-parse HEAD解析分支git rev-parse --abbrev-ref HEADgit shortlog显示提交日志摘要git shortlog按作者分组git shortlog -s -n这个表格包含了大部分常用的 Git 命令及其用法示例。如果你有具体的命令需求或需要更多详细信息请查阅 Git 官方文档。