Git精讲

Git基本操作

创建Git本地仓库

  • git init
  • git clone

配置Git

git config [--global] user.name "Your Name"
git config [--global] user.email "email@example.com"

–global是一个可选项。如果使用了该选项,表示这台机器上所有的Git仓库都会使用这个配置。如果你希望在不同的仓库中使用不同的name和email,那么就不用global这个选项。

查看配置的命令:

git config -l

删除对应的配置的命令为:

git config [--global] --unset user.name
git config [--global] --unset user.email

认识工作区,暂存区,版本库

  • 工作区:是指电脑上你要写代码或文件的目录。
  • 暂存区:英文名是stage或者index。一般存放在.git目录下的index文件(.git/index)中,我们把暂存区有时也叫索引(index)。
  • 版本库:又叫仓库。工作区有一个隐藏目录,它不算工作区,而是Git的版本库。这个版本库里面的所有文件都可以被Git管理起来,每个文件的修改,删除,Git都可以追踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以还原。

在这里插入图片描述

  • 图中左侧为工作区,右侧为版本库。Git的版本库里面存了很多东西,其中最重要的是暂存区。
  • 在创建Git版本库的时候,Git会为我们自动创建一个唯一的master分支,以及指向master的一个指针叫做HEAD。
  • 当对工作区修改或者新增文件的时候执行git add命令,暂存区目录树的文件索引会被更新。
  • 当执行提交操作git commit的时候,master分支会做相应的更新,可以理解为暂存区的目录树才会真正写到版本库中。

基本命令

git log:可以使用git log来查看历史提交记录。
在这里插入图片描述

如果嫌输出点信息太多,看的眼花缭乱,可以试试加上--pretty=oneline参数:

在这里插入图片描述

需要说明的是,我们看到的⼀⼤串类似 23807c5…56eed6 的是每次提交的 commit id (版本号),Git 的 commit id 不是1,2,3……递增的数字,⽽是⼀个 SHA1 计算出来的⼀个⾮常⼤的数字,⽤⼗六进制表⽰。

查看.git文件

VQ1T7VH07X:git-practice bytedance$ tree .git/
.git/
├── COMMIT_EDITMSG
├── HEAD
├── config
├── description
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── fsmonitor-watchman.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── pre-merge-commit.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   ├── pre-receive.sample
│   ├── prepare-commit-msg.sample
│   ├── push-to-checkout.sample
│   └── update.sample
├── index
├── info
│   └── exclude
├── logs
│   ├── HEAD
│   └── refs
│       ├── heads
│       │   └── master
│       └── remotes
│           └── origin
│               └── HEAD
├── objects
│   ├── 68
│   │   └── d4663301d2411e07243ce6ffd05c913541267c
│   ├── 83
│   │   └── b3c1c9e9a278abb737e810dcfe208295660c4f
│   ├── a8
│   │   └── 57e6ed933bee02a6889a95d6189c3ee1405497
│   ├── info
│   └── pack
│       ├── pack-42d887f3aa9c650926611499c530369ad0b83da6.idx
│       └── pack-42d887f3aa9c650926611499c530369ad0b83da6.pack
├── packed-refs
└── refs
    ├── heads
    │   └── master
    ├── remotes
    │   └── origin
    │       └── HEAD
    └── tags

19 directories, 30 files
  • index就是暂存区,add之后的内容添加到这里

  • HEAD是我们默认指向master分支到指针

    默认的master分支其实就是:

    在这里插入图片描述

    打印的这一串哈希值是保存的最新的commit id

  • object为Git的对象库,里面包含了创建各种版本库对象以及内容。当执行git add命令的时候,暂存区的目录树被更新,同时工作区的文件内容被写入到对象库中的一个新的对象中,就位于.git/object目录下,让我们来看看这些对象有何用处。

    VQ1T7VH07X:git-practice bytedance$ ls .git/objects/
    68	83	a8	info	pack
    

    查找Object的时候要将commit id 分成两个部分,其前2位是文件夹名称,后38位是文件名称。

    找到这个文件之后,一般不能直接看到里面是什么,该类文件是经过sha加密过的文件,好在我们可以使用git cat-file 命令来查看版本库对象的内容。

    在这里插入图片描述

    这个就是我们最近一次的提交。

    其中还有一行tree 83b3c1c9e9a278abb737e810dcfe208295660c4f,我们使用同样的方式去看看结果:

    VQ1T7VH07X:git-practice bytedance$ git cat-file -p 83b3c1c9e9a278abb737e810dcfe208295660c4f
    100644 blob a857e6ed933bee02a6889a95d6189c3ee1405497	README.md
    

    我们再看README对应的a857e6ed933bee02a6889a95d6189c3ee1405497:

    VQ1T7VH07X:git-practice bytedance$ git cat-file -p a857e6ed933bee02a6889a95d6189c3ee1405497
    # git-practice
    git实践
    我是李鑫阳,我其实很喜欢你
    

    可以看到我们对README做的修改被git记录了下来。

总结
  1. index: 暂存区, git add 后会更新该内容。
  2. HEAD: 默认指向 master 分⽀的⼀个指针。
  3. refs/heads/master: ⽂件⾥保存当前 master 分⽀的最新 commit id 。
  4. objects: 包含了创建的各种版本库对象及内容,可以简单理解为放了 git 维护的所有修改。

修改文件

Git追踪的是修改,而非文件

我们对README文件做一些修改:

在这里插入图片描述

我们可以使用git status 命令来查看在你上次体检之后是否对文件有进行再次修改。

在这里插入图片描述

上面的结果告诉我们README被修改过了,但是我们不知道具体哪些地方被修改了。因此使用git diff命令

在这里插入图片描述

然后知道了哪些地方被修改了,我们再去add和commit就放心了。

版本回退

之前我们也提到过,Git 能够管理⽂件的历史版本,这也是版本控制器重要的能⼒。如果有⼀天你发现之前前的⼯作做的出现了很⼤的问题,需要在某个特定的历史版本重新开始,这个时候,就需要版本回退的功了。

执行git reset命令用于版本回退,可以指定回退某一次提交的版本。回退本质是要将版本库中的内容进行回退,工作区或者暂存区是否回退要由命令参数决定。

git reset命令语法格式为: git reset [--soft | --mixed | --hard] [HEAD]

  • --mixed为默认选项,使用的时候可以不用带参数。该参数将暂存区的内容退回为指定提交版本内容,工作区内容保持不变。
  • --soft参数对于工作区和暂存区的内容都不变,只是将版本库回退到某个指定版本。
  • --hard参数将暂存区与工作区都退回到指定版本。切记工作区有未提交到代码时不要用这个命令,因为工作区会回滚,因为工作区会回滚,你没有提交到代码就再也找不到回来了。
  • HEAD说明:
    • 可以直接写成commit id,表示指定退回到版本
    • HEAD表示当前版本
    • HEAD^表示上一个版本
    • HEAD^^表示上上个版本
    • 以此类推
  • 可以使用~数字表示
    • HEAD~0表示当前版本
    • HEAD~1表示上一个版本
    • HEAD~2表示上上个版本
    • 以此类推
example

在这里插入图片描述

可以看到version1,version2,version3的提交。如果发现version3写的有问题,想回到version2,重新基于version2进行编写。由于我们在这里希望的是将工作区的内容也回退到version2版本。我们这里希望将工作区的内容也回退到version2,因此需要用到–hard参数。

在这里插入图片描述

一般情况下到这里就结束了,但是如果我现在后悔了,想再回退到version3怎么办?我们还是可以继续用git reset命令。但是我们必须要拿到version3的commit id去指定回退的版本。git log可以找到commit id,但是我们更改了HEAD指向的最新版本之后,git log就已经无法找到version3的commit版本了,这个时候我们需要使用git reflog命令。这个命令用来记录本地的每一次命令。

在这里插入图片描述

这样就可以找到所有的操作记录了,但是2a65701这是个什么东西呢?这个是version3的commit id部分。Git版本回退的时候也可以使用部分commit id来代表目标版本。

在这里插入图片描述

这个时候git log也是已经可以看到的了。

可在实际开发中,由于长时间的开发,导致commit id找不到了,但是突然某一天我又想回退到version3,那么该如何操作呢?我告诉你,已经不可能了

值得说的是,Git 的版本回退速度⾮常快,因为 Git 在内部有个指向当前分⽀(此处是master)的HEAD 指针, refs/heads/master ⽂件⾥保存当前 master 分⽀的最新 commit id 。当我们在回退版本的时候,Git 仅仅是给 refs/heads/master 中存储⼀个特定的version,可以简单理解成如下⽰意图:

在这里插入图片描述

撤销修改

如果我们在工作区写了很长时间的代码,越写越写不下去,觉得自己写的太垃圾了,想恢复到上一个版本

情况一:对于工作区的代码,还没有add

可以使用git checkout -- [file]命令让工作区的文件回到最近一次add或者commit的状态。

在这里插入图片描述

情况二:已经add,但是没有commit

在这里插入图片描述

我们回顾一下git reset参数,该命令使用–mixed参数,可以将暂存区的内容退回为指定的版本内容,但工作区文件保持不变。

在这里插入图片描述

可以看到暂存区是干净的,工作区有修改。现在相当于没有add了,那么使用git checkout -- [file]命令就可以了。

在这里插入图片描述

情况三:已经add,并且已经commit了

使用git reset --hard HEAD^,前提是你没有把代码推送到远程仓库,如果你把代码推送到了远程仓库就真的惨了。

删除文件

git rm [file]可以把文件从暂存区和工作区中删除并且commit。

分支管理

在版本回退里面,每次体检Git都把他们串成一条时间线,这条时间线可以理解成是一个分支。截止到目前为止,只有一条时间线,在Git里面,这个分支叫做主分支,即master分支。

在这里插入图片描述

再来理解一下HEAD,HEAD严格来说不是指向体检,而是指向master,master才指向体检,所以HEAD指向的是当前的分支。

每次提交,master分支都会向前移动一步,这样随着你不断的提交,master分支的线也会越来越长,而HEAD只要一直指向master分支即可指出当前分支。

通过查看当前的版本库,我们也可以清晰的理出思路:

VQ1T7VH07X:git-practice bytedance$ cat .git/HEAD
ref: refs/heads/master
VQ1T7VH07X:git-practice bytedance$ cat .git/refs/heads/master
d0b06aae554721d7778698681dd27d05f6417fff

创建分支

在这里插入图片描述

发现目前dev和master都指向同一个修改。并可以验证得到HEAD目前是指向master的。

一张图总结:

在这里插入图片描述

切换分支

在这里插入图片描述

我们发现HEAD已经指向了dev,就表示我们已经成功切换到了dev上面。

接下来,在dev分支下修改README文件,新增一行内容并进行一次提交操作。

这个时候图就成了这个样子了:

在这里插入图片描述

合并分支

为了能在master主分支上看到新的提交,就需要将dev分支合并到master分支,实例如下:

在这里插入图片描述

git merge命令用于合并指定分支到当前分支。合并后,master就能看到dev分支提交到内容了。此时的状态如下所示。

在这里插入图片描述

Fast- forward代表快进模式,也就是直接把master分支执行dev的当前提交,所以合并速度非常快。当然,也不是每一次合并都能Fast- forward。

删除分支

git branch -d dev

在这里插入图片描述

合并冲突

可是,在实际分支合并的时候,并不是想合并就合成功的,有时候可能会遇到代码冲突的问题。

创建一个dev1分支,修改文件内容,然后在master分支上面也修改内容,且修改的位置有冲突。

此时master和dev1的分支有了各自的提交:

在这里插入图片描述

此时切换回master分支之后使用git merge dev1

这个时候git会告诉你已经冲突了,无法merge,并且会告你的冲突的地方是哪个文件,这个时候打开这个文件,会发现git已经标记出来了冲突的内容:

在这里插入图片描述

这个时候需要手动处理冲突。

解决冲突之后此时的状态变成了:

在这里插入图片描述

使用git log可以很清楚的看到这个问题。

在这里插入图片描述

git log --graph --pretty=oneline --abbrev-commit

分支管理策略

通常合并分支的时候,如果可能,git会使用Fast forward模式。如果我们使用Fast forward模式,那么形成的合并结果是什么呢?

在这里插入图片描述

在这种 Fast forward 模式下,删除分⽀后,查看分⽀历史时,会丢掉分⽀信息,看不出来最新提交到底是 merge 进来的还是正常提交的。在这种Fast forward模式下,删除分支之后,查看分支时,会丢掉分支信息,看不出来最新提交到底是merge还是正常提交的。

但是在合并冲突部分,我们看到通过解决分支冲突,我们多了一次commit,最终的状态为:

在这里插入图片描述

那么这个就不说fast forward模式了,这样的好处是从分支历史上可以看出分支信息。例如我们现在删除了在合并冲突部分创建的dev1分支,但依旧能看到master其实是由其他分支合并得到的。

Git支持我们强制禁用Fast forward模式。那么就会在merge的时候生成一个新的commit,这样从分支历史上就可以看到分支信息。

git merge --no-ff -m "merge with no-ff" dev2

在这里插入图片描述

不使用Fast forward的话是这个样子的。

在这里插入图片描述

分支策略

master分支是非常文档的,也就是仅仅用来发布新版本,平时不能在上面干活。

平时在dev分支上面干活,dev分支是不稳定的,到某个时候,例如1.0版本发布的时候,再把dev分支合并到master上面,在master上面发布1.0版本。

因此团队合作的分支看起来其实是这个样子的:

在这里插入图片描述

bug分支

假如我们现在正在 dev2 分⽀上进⾏开发,开发到⼀半,突然发现 master 分⽀上⾯有 bug,需要解决。在Git中,每个 bug 都可以通过⼀个新的临时分⽀来修复,修复后,合并分⽀,然后将临时分⽀删除。

可是现在dev2的代码在工作区中开发了一半,还无法提交,怎么办?

例如这样:

在这里插入图片描述

Git提供了git stash命令,可以将当前的工作区信息进行储藏,被储藏的内容可以在将来某个时间恢复出来。

VQ1T7VH07X:git-practice bytedance$ git stash
Saved working directory and index state WIP on dev: 33de037 add

储藏了dev工作区之后,由于我们要给予master分支修复bug,所以需要切回master分支,再新建临时分支来修复。

hyb@139-159-150-152:~/gitcode$ git checkout master # 切回master
Switched to branch 'master'
hyb@139-159-150-152:~/gitcode$ git checkout -b fix_bug # 新建并切换到 fix_bug 分⽀
Switched to a new branch 'fix_bug'
hyb@139-159-150-152:~/gitcode$ vim ReadMe 
hyb@139-159-150-152:~/gitcode$ cat ReadMe 
hello bit
hello git
hello world
hello version1
hello version2
hello version3
write bbb for new branch
a,b,c,d,e # 修复bug--忘记写e
hyb@139-159-150-152:~/gitcode$ git add ReadMe # 重新add,commit
hyb@139-159-150-152:~/gitcode$ git commit -m"fix bug"
[fix_bug 4bbc0c4] fix bug
 1 file changed, 1 insertion(+), 1 deletion(-)

修复完成,切换回master分支,并完成合并,最后删除fix_bug分支。

hyb@139-159-150-152:~/gitcode$ git checkout master 
Switched to branch 'master'
hyb@139-159-150-152:~/gitcode$ git merge --no-ff -m"merge fix_bug branch" fix_bu
Merge made by the 'recursive' strategy.
 ReadMe | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

这个时候回到dev分支,工作区是干净,刚才到工作区去哪里了,用git stash list进行查看。

在这里插入图片描述

使用git stash pop恢复,恢复的同时会把stash删除。再次查看的时候已经没有现场可以恢复了。

另外,恢复现场也可以采⽤ git stash apply 恢复,但是恢复后,stash内容并不删除,你需要⽤ git stash drop 来删除;你可以多次stash,恢复的时候,先⽤ git stash list 查看,然后恢复指定的stash,⽤命令git stash apply stash@{0}

但我们注意到了,修复 bug 的内容,并没有在 dev2 上显⽰。此时的状态图为:

在这里插入图片描述

Master 分⽀⽬前最新的提交,是要领先于新建 dev2 时基于的 master 分⽀的提交的,所以我们在 dev2 中当然看不⻅修复 bug 的相关代码。

我们的最终⽬的是要让 master 合并 dev2 分⽀的,那么正常情况下我们切回 master 分⽀直接合并即可,但这样其实是有⼀定⻛险的。是因为在合并分⽀时可能会有冲突,⽽代码冲突需要我们⼿动解决(在 master 上解决)。我们⽆法保证对于冲突问题可以正确地⼀次性解决掉,因为在实际的项⽬中,代码冲突不只⼀两⾏那么简单,有可能⼏⼗上百⾏,甚⾄更多,解决的过程中难免⼿误出错,导致错误的代码被合并到 master 上。此时的状态为:

在这里插入图片描述

解决这个问题一个好的建议就是:在自己的分支上合并一下master,然后再让master合并dev。这样做的好处是有冲突的时候可以做本地分支解决并且测试,而不影响master。此时的状态为:

在这里插入图片描述

VQ1T7VH07X:git-practice bytedance$ git branch
* dev
  master
VQ1T7VH07X:git-practice bytedance$ vim README.md
VQ1T7VH07X:git-practice bytedance$ git checkout master
M	README.md
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 22 commits.
  (use "git push" to publish your local commits)
VQ1T7VH07X:git-practice bytedance$ vim README.md
VQ1T7VH07X:git-practice bytedance$ git add .
VQ1T7VH07X:git-practice bytedance$ git commit -m "sst"
[master fece00e] sst
 1 file changed, 4 insertions(+), 1 deletion(-)
VQ1T7VH07X:git-practice bytedance$ git checkout dev
Switched to branch 'dev'
Your branch is behind 'master' by 1 commit, and can be fast-forwarded.
  (use "git pull" to update your local branch)
VQ1T7VH07X:git-practice bytedance$ vim README.md
VQ1T7VH07X:git-practice bytedance$ git add .
VQ1T7VH07X:git-practice bytedance$ git commit -m "aaa"
[dev 5b63b36] aaa
 1 file changed, 1 insertion(+), 1 deletion(-)
VQ1T7VH07X:git-practice bytedance$ git merge master
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.
VQ1T7VH07X:git-practice bytedance$ vim README.md
VQ1T7VH07X:git-practice bytedance$ git merge --no-ff -m "merge master branch" master
error: Merging is not possible because you have unmerged files.
hint: Fix them up in the work tree, and then use 'git add/rm <file>'
hint: as appropriate to mark resolution and make a commit.
fatal: Exiting because of an unresolved conflict.
VQ1T7VH07X:git-practice bytedance$ git add .
VQ1T7VH07X:git-practice bytedance$ git commit -m "sst"
[dev 6f01b8a] sst
VQ1T7VH07X:git-practice bytedance$ git merge --no-ff -m "merge master branch" master
Already up to date.
VQ1T7VH07X:git-practice bytedance$ git merge master
Already up to date.
VQ1T7VH07X:git-practice bytedance$ vim README.md
VQ1T7VH07X:git-practice bytedance$ vim README.md
VQ1T7VH07X:git-practice bytedance$ git add .
VQ1T7VH07X:git-practice bytedance$ git commit -m "lixinyang"
[dev e35cfcf] lixinyang
 1 file changed, 1 insertion(+)
VQ1T7VH07X:git-practice bytedance$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 23 commits.
  (use "git push" to publish your local commits)
VQ1T7VH07X:git-practice bytedance$ git merge dev
Updating fece00e..e35cfcf
Fast-forward
 README.md | 1 +
 1 file changed, 1 insertion(+)

远程操作

当我们从远程仓库克隆后,实际上 Git 会⾃动把本地的 master 分⽀和远程的 master 分⽀对应起来,并且,远程仓库的默认名称是 origin 。在本地我们可以使⽤ git remote 命令,来查看远程库的信息,如:

VQ1T7VH07X:git-practice bytedance$ git remote
origin

VQ1T7VH07X:git-practice bytedance$ git remote -v
origin	https://github.com/sjmshsh/git-practice.git (fetch)
origin	https://github.com/sjmshsh/git-practice.git (push)

向远程仓库推送

git push <远程主机名> <本地分⽀名>:<远程分⽀名>
# 如果本地分⽀名与远程分⽀名相同,则可以省略冒号:
git push <远程主机名> <本地分⽀名>


git pull <远程主机名> <远程分⽀名>:<本地分⽀名>
# 如果远程分⽀是与当前分⽀合并,则冒号后⾯的部分可以省略。
git pull <远程主机名> <远程分⽀名>

git pull 和 git fetch的区别

再来看一次git的工作流程图,如下所示:

在这里插入图片描述

可以看到,git fetch是将远程主机的最新内容拉到本地,用户在检查了以后决定是否合并到工作本机分支中

可以看到,git fetch是将远程主机的最新内容拉到本地,用户在检查了以后决定是否合并到工作本机分支中

git pull 则是将远程主机的最新内容拉下来后直接合并,即:git pull = git fetch + git merge,这样可能会产生冲突,需要手动解决。

在我们本地的git文件中对应也存储了git本地仓库分支的commit ID 和 跟踪的远程分支的commit ID,对应文件如下:

  • .git/refs/head/[本地分支]
  • .git/refs/remotes/[正在跟踪的分支]

使用 git fetch更新代码,本地的库中mastercommitID不变

但是与git上面关联的那个orign/mastercommit ID发生改变

这时候我们本地相当于存储了两个代码的版本号,我们还要通过merge去合并这两个不同的代码版本

在这里插入图片描述

也就是fetch的时候本地的master没有变化,但是与远程仓关联的那个版本号被更新了,接下来就是在本地merge合并这两个版本号的代码

相比之下,使用git pull就更加简单粗暴,会将本地的代码更新至远程仓库里面最新的代码版本,如下图:

在这里插入图片描述

一般远端仓库里有新的内容更新,当我们需要把新内容下载的时候,就使用到git pull或者git fetch命令

fetch

用法如下:

git fetch <远程主机名> <远程分支名>:<本地分支名>

例如从远程的origin仓库的master分支下载代码到本地并新建一个temp分支

git fetch origin master:temp

如果上述没有冒号,则表示将远程origin仓库的master分支拉取下来到本地当前分支

这里git fetch不会进行合并,执行后需要手动执行git merge合并,如下:

git merge temp

pull

两者的用法十分相似,pull用法如下:

git pull <远程主机名> <远程分支名>:<本地分支名>

例如将远程主机originmaster分支拉取过来,与本地的branchtest分支合并,命令如下:

git pull origin master:branchtest

同样如果上述没有冒号,则表示将远程origin仓库的master分支拉取下来与本地当前分支合并

区别

相同点:

  • 在作用上他们的功能是大致相同的,都是起到了更新代码的作用

不同点:

  • git pull是相当于从远程仓库获取最新版本,然后再与本地分支merge,即git pull = git fetch + git merge
  • 相比起来,git fetch 更安全也更符合实际要求,在 merge 前,我们可以查看更新情况,根据实际情况再决定是否合并

git本地分支和远程分支建立追踪关系的三种方式

  • 手动建立追踪关系

    git branch --set-upstream-to=<远程主机名>/<远程分支名> <本地分支名>
    
  • push时建立追踪关系

    git push -u <远程主机名><本地分支名>
    
  • 新建分支的时候建立追踪关系

    git checkout -b <本地分支名> <远程主机名>/<远程分支名>
    
  • 查看追踪关系

    git branch -vv
    

远程分支

远程引用是对远程仓库的引用,包括分支,标签等等。

  • 远程跟踪分支是远程分支状态的引用
  • 一旦你进行了网络通信, Git 就会为你移动它们以精确反映远程仓库的状态
  • 该分支在远程仓库中的位置就是最后一次连接到它们的位置

命名格式

<remote>/</branch>

为何叫origin?

  • git clone 命令会给远程仓库默认命名为 origin,然后拉取它的所有数据, 创建一个指向它的 master 分支的指针,并且在本地将其命名为 origin/master【远程分支 origin/master】
  • Git 也会给你一个与 origin 的 master 分支在指向同一个地方的本地 master 分支,这样你就有工作的基础【本地分支 master】
重点
  • origin 和 master 一样,没有特殊的含义
  • 只是 git init 时默认的起始分支名字取得就是 master
  • 而 git clone 默认给远程仓库名字取得就是 origin

假设指定远程仓库名字

git clone -o lixinyang

那么默认远程分支的名字就是lixinyang/master

在这里插入图片描述

克隆之后的远程仓库与本地仓库

  • 有人在 git.ourcompany.com 的 master 分支上 push 了新的提交
  • 而自己在本地的 master 分支上也做了提交但是没有 push
  • 只要本地不拉取最新的数据,那么本地的远程分支(origin/master)还是指向之前的 f4265 节点

在这里插入图片描述

本地与远程的工作可以分叉

将本地的远程仓库和服务器上的远程仓库同步数据

git fetch <remote>
git fetch origin
  • 这个命令查找origin是哪个服务器(在本例中,它是 git.ourcompany.com
  • 从中拉去本地没有的数据,并且更新本地数据库
  • 移动origin/master指针到更新之后的位置

在这里插入图片描述

可以看到,因为本地的 master 分支已经有过新的提交,所以和 origin/master 远程分支处于分叉状态。

git fetch更新你的远程跟踪分支

现在有个新的 git 服务器位于 git.team1.ourcompany.com

当有多个远程仓库与远程分支的情况下,要怎么添加新的远程仓库引用到本地项目呢?

git remote add <remote> <git 服务器url>

在这里插入图片描述

添加另一个远程仓库

抓取新添加的远程仓库在本地没有的数据

git fetch teamone
  • 因为那台服务器上现有的数据是 origin 服务器上的一个子集,
  • 所以 Git 并不会抓取数据而是会设置远程跟踪分支 teamone/master 指向 teamonemaster 分支。

在这里插入图片描述

推送至远程跟踪分支

git push <remote><branch>

将本地的serverfix分支推送到远程仓库上的awesomebranch分支

git push origin serverfix:awesomebranch

下一次其他协作者从服务器上拉取数据时,他们会在本地生成一个远程分支 origin/serverfix,指向服务器的 serverfix 分支的引用:

$ git fetch origin
remote: Counting objects: 7, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 3 (delta 0)
Unpacking objects: 100% (3/3), done.
From https://github.com/schacon/simplegit
 * [new branch]      serverfix    -> origin/serverfix

这样操作,本地不会自动新增一个 serverfix 分支,只是有一个不可修改的 origin/serverfix 指针

git merge origin/serverfix 

这也是将 origin/serverfix 远程分支下的内容合并到本地当前所在分支

$ git checkout -b serverfix origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix' 

这样可以在本地新建一个 serverfix 分支,并且和 origin/serverfix 远程分支指向同一个提交内容

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/165892.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Network(三)动态路由与ACL配置

一 三层交换机 1 三层交换机概述 三层交换二层交换三层转发 2 虚拟接口概述 在三层交换机上配置的VLAN接口为虚拟接口&#xff0c;使用Vlanif&#xff08;VLAN虚拟接口&#xff09;实现VLAN间路由&#xff0c;VLAN接口的引入使得应用更加灵活 三层交换机VLAN间通信的转发…

Cross-View Transformers for Real-Time Map-View Semantic Segmentation 论文阅读

论文链接 Cross-View Transformers for Real-Time Map-View Semantic Segmentation 0. Abstract 提出了 Cross-View Transformers &#xff0c;一种基于注意力的高效模型&#xff0c;用于来自多个摄像机的地图视图语义分割使用相机感知的跨视图注意机制隐式学习从单个相机视…

第93步 深度学习图像分割:PSPNet建模

基于WIN10的64位系统演示 一、写在前面 本期&#xff0c;我们继续学习深度学习图像分割系列的另一个模型&#xff0c;PSPNet。 二、PSPNet简介 &#xff08;1&#xff09;金字塔池化模块 (Pyramid Pooling Module) PSPNet的核心是其金字塔池化模块&#xff0c;该模块能够捕…

4 redis的HyperLogLog入门原理

一、HyperLogLog&#xff08;字符串类型&#xff09; 需求&#xff1a;大型网站(不在大厂基本上用不到) 每个网页每天的 UV 数据(独立访客)&#xff0c;统计如何实现&#xff1f;(尽量少的占用存储空间) Redis 提供了 HyperLogLog 数据结构就是用来解决这种统计问题的。Hyper…

[ 云计算 | AWS 实践 ] Java 如何重命名 Amazon S3 中的文件和文件夹

本文收录于【#云计算入门与实践 - AWS】专栏中&#xff0c;收录 AWS 入门与实践相关博文。 本文同步于个人公众号&#xff1a;【云计算洞察】 更多关于云计算技术内容敬请关注&#xff1a;CSDN【#云计算入门与实践 - AWS】专栏。 本系列已更新博文&#xff1a; [ 云计算 | …

六、文件上传漏洞

下面内容部分&#xff1a;参考 一、文件上传漏洞解释 解释&#xff1a;文件上传漏洞一般指的就是用户能够绕过服务器的规则设置将自己的木马程序放置于服务器实现远程shell&#xff08;例如使用蚁剑远程连接&#xff09;&#xff0c;常见的木马有一句话木马(php) 无需启用sho…

各类语言真实性能比较列表

这篇文章是我所做或将要做的所有真实世界性能比较的索引。如果你对想要看到的其他真实世界案例有建议&#xff0c;请在评论中添加。 用例 1 — JWT 验证 & MySQL 查询 该用例包括&#xff1a; 从授权头部获取 JWT验证 JWT 并从声明中获取电子邮件使用电子邮件执行 MySQL…

〖大前端 - 基础入门三大核心之JS篇㊳〗- DOM访问元素节点

说明&#xff1a;该文属于 大前端全栈架构白宝书专栏&#xff0c;目前阶段免费&#xff0c;如需要项目实战或者是体系化资源&#xff0c;文末名片加V&#xff01;作者&#xff1a;不渴望力量的哈士奇(哈哥)&#xff0c;十余年工作经验, 从事过全栈研发、产品经理等工作&#xf…

SQL练习02

1.买下所有产品的客户 SQL Create table If Not Exists Customer (customer_id int, product_key int); Create table Product (product_key int); Truncate table Customer; insert into Customer (customer_id, product_key) values (1, 5); insert into Customer (customer_…

鸿蒙:使用Stack、ContentTable、Flex等组件和布局实现一个显示界面

效果展示 一.概述 跟随官网继续HarmonyOS学习 本篇博文实现一个食物详情页的开发Demo 通过这个开发过程学习如何使用容器组件Stack、Flex和基本组件Image、Text&#xff0c;构建用户自定义组件&#xff0c;完成图文并茂的食物介绍 二.构建Stack布局 1.食物名称 创建Stack…

YOLOv5 学习记录

文章目录 整体概况数据增强与前处理自适应Anchor的计算Lettorbox 架构SiLU激活函数YOLOv5改进点SSPF 模块 正负样本匹配损失函数 整体概况 YOLOv5 是一个基于 Anchor 的单阶段目标检测&#xff0c;其主要分为以下 5 个阶段&#xff1a; 1、输入端&#xff1a;Mosaic 数据增强、…

【LeetCode刷题-树】--100.相同的树

100.相同的树 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …

【数据结构】C语言实现队列

目录 前言 1. 队列 1.1 队列的概念 1.2 队列的结构 2. 队列的实现 2.1 队列的定义 2.2 队列的初始化 2.3 入队 2.4 出队 2.5 获取队头元素 2.6 获取队尾元素 2.7 判断空队列 2.8 队列的销毁 3. 队列完整源码 Queue.h Queue.c &#x1f388;个人主页&#xff1a…

获取每个部门中当前员工薪水最高的相关信息

个人网站 首发于公众号小肖学数据分析 描述 有一个员工表dept_emp简况如下: 有一个薪水表salaries简况如下: 获取每个部门中当前员工薪水最高的相关信息&#xff0c;给出dept_no, emp_no以及其对应的salary&#xff0c;按照部门编号dept_no升序排列&#xff0c;以上例子输出…

【NI-DAQmx入门】校准

1.设备定期校准的理由 随着时间的推移电子器件的特性会发生自然漂移&#xff0c;可能会导致测量结果的不准确性。防止出现良品和差品筛选出错的情况满足行业国际标准降低设备出现故障的风险使测量结果更具备参考性 2.查找NI设备的校准间隔。 定期校准会使DAQ设备的精度保持在…

电路的基本原理

文章目录 一、算数逻辑单元(ALU)1、功能2、组成 二、电路基本知识1、逻辑运算2、复合逻辑 三、加法器实现1、一位加法器2、串行加法器3、并行加法器 一、算数逻辑单元(ALU) 1、功能 算术运算&#xff1a;加、减、乘、除等 逻辑运算&#xff1a;与、或、非、异或等 辅助功能&am…

C语言ASCII码排序(1086: ASCII码排序(多实例测试))

题目描述 输入三个字符后&#xff0c;按各字符的ASCII码从小到大的顺序输出这三个字符。 输入&#xff1a;输入数据有多组&#xff0c;每组占一行&#xff0c;由三个字符组成&#xff0c;之间无空格。chu 输出&#xff1a;对于每组输入数据&#xff0c;输出一行&#xff0c;字符…

云课五分钟-0Cg++默认版本和升级-std=c++17

前篇&#xff1a; 云课五分钟-0B快速排序C示例代码-注释和编译指令 视频&#xff1a; 云课五分钟-0Cg默认版本和升级-stdc17 文本&#xff1a; 在Linux系统中&#xff0c;可以通过以下步骤升级g&#xff1a; 打开终端&#xff0c;使用root权限或者sudo权限登录。输入以下命令…

cad提示由于找不到mfc140u.dll,无法继续执行代码怎么修复

在Windows操作系统中&#xff0c;mfc140u.dll是一个重要的文件&#xff0c;很多软件运行都需要它&#xff0c;它属于Microsoft Visual C库的一部分。许多基于C的开发项目都依赖于这个文件&#xff0c;如果在使用过程中出现丢失现象&#xff0c;可能导致相关软件或游戏无法正常运…

Linux管道的工作过程

常用的匿名管道&#xff08;Anonymous Pipes&#xff09;&#xff0c;也即将多个命令串起来的竖线。管道的创建&#xff0c;需要通过下面这个系统调用。 int pipe(int fd[2]) 我们创建了一个管道 pipe&#xff0c;返回了两个文件描述符&#xff0c;这表示管道的两端&#xff…