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└── tags19 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 bug1 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
* devmaster
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] sst1 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] aaa1 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] lixinyang1 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-forwardREADME.md | 1 +1 file changed, 1 insertion(+)

远程操作

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

VQ1T7VH07X:git-practice bytedance$ git remote
originVQ1T7VH07X: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.rhkb.cn/news/198229.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

6 Redis的慢查询配置

1、redis的命令执行流程 redis的慢查询只针对步骤3 默认情况下&#xff0c;慢查询的阈值是10ms 在配置文件中进行配置 //这个参数的单位为微秒 //如果将这个值设置为负数&#xff0c;则会禁用慢日志功能 //如果将其设置为0&#xff0c;则会强制记录每个命令 slowlog-log-slow…

【C++历练之路】list的重要接口||底层逻辑的三个封装以及模拟实现

W...Y的主页 &#x1f60a; 代码仓库分享&#x1f495; &#x1f354;前言&#xff1a; 在C的世界中&#xff0c;有一种数据结构&#xff0c;它不仅像一个神奇的瑰宝匣&#xff0c;还像一位能够在数据的海洋中航行的智慧舵手。这就是C中的list&#xff0c;一个引人入胜的工具…

立仪科技光谱共焦在半导体领域的应用

半导体技术在近年来以极快的速度发展&#xff0c;对质量和精密度的要求也不断提升。在这样的背景下&#xff0c;用于材料与设备研究的先进检测技术如光谱共焦成像将自然地找到一席之地。下面我们将详细探讨一下光谱共焦在半导体领域中的应用。 光谱共焦技术&#xff0c;通过在细…

【DevOps】Git 图文详解(四):Git 使用入门

Git 图文详解&#xff08;四&#xff09;&#xff1a;Git 使用入门 1.创建仓库2.暂存区 add3.提交 commit 记录4.Git 的 “指针” 引用5.提交的唯一标识 id&#xff0c;HEAD~n 是什么意思&#xff1f;6.比较 diff 1.创建仓库 创建本地仓库的方法有两种&#xff1a; 一种是创建…

MongoDB之索引和聚合

文章目录 一、索引1、说明2、原理3、相关操作3.1、创建索引3.2、查看集合索引3.3、查看集合索引大小3.4、删除集合所有索引&#xff08;不包含_id索引&#xff09;3.5、删除集合指定索引 4、复合索引 二、聚合1、说明2、使用 总结 一、索引 1、说明 索引通常能够极大的提高查…

CSS的选择器(一篇文章齐全)

目录 Day26&#xff1a;CSS的选择器 1、CSS的引入方式 2、CSS的选择器 2.1 基本选择器​编辑 2.2 组合选择器 2.3 属性选择器 2.4 伪类选择器 2.5 样式继承 2.6 选择器优先级 3、CSS的属性操作 3.1 文本属性 3.2 背景属性 3.3 边框属性 3.4 列表属性 3.5 dispal…

Hive调优

1.参数配置优化 设定Hive参数有三种方式&#xff1a; &#xff08;1&#xff09;配置Hive文件 当修改配置Hive文件的设定后&#xff0c;对本机启动的所有Hive进程都有效&#xff0c;因此配置是全局性的。 一般地&#xff0c;Hive的配置文件包括两部分&#xff1a; a&#xff…

Node.js之TCP(net)

Hi I’m Shendi Node.js之TCP&#xff08;net&#xff09; 最近使用Nodejs编写程序&#xff0c;需要用到自己编写的分布式工具&#xff0c;于是需要将Java版的用NodeJs重新写一遍&#xff0c;需要使用到TCP通信&#xff0c;于是在这里记录下Node.js TCP 的使用方法 依赖 需要使…

【面试经典150 | 算术平方根】

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;数学表达式方法二&#xff1a;二分法 其他语言python3 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并…

Asp.net MVC Api项目搭建

整个解决方案按照分层思想来划分不同功能模块&#xff0c;以提供User服务的Api为需求&#xff0c;各个层次的具体实现如下所示&#xff1a; 1、新建数据库User表 数据库使用SQLExpress版本&#xff0c;表的定义如下所示&#xff1a; CREATE TABLE [dbo].[User] ([Id] …

YOLOv8改进 | 2023 | InnerIoU、InnerSIoU、InnerWIoU、FoucsIoU等损失函数

论文地址&#xff1a;官方Inner-IoU论文地址点击即可跳转 官方代码地址&#xff1a;官方代码地址-官方只放出了两种结合方式CIoU、SIoU 本位改进地址&#xff1a; 文末提供完整代码块-包括InnerEIoU、InnerCIoU、InnerDIoU等七种结合方式和其Focus变种 一、本文介绍 本文给…

手写消息队列(基于RabbitMQ)

一、什么是消息队列&#xff1f; 提到消息队列是否唤醒了你脑海深处的记忆&#xff1f;回看前面的这篇文章&#xff1a;《Java 多线程系列Ⅳ&#xff08;单例模式阻塞式队列定时器线程池&#xff09;》&#xff0c;其中我们在介绍阻塞队列时说过&#xff0c;阻塞队列最大的用途…

PWM实验

PWM相关概念 PWM:脉冲宽度调制定时器 脉冲&#xff1a;方波信号&#xff0c;高低电平变化产生方波 周期&#xff1a;高低电平变化所需要时间 频率&#xff1a;1s钟可以产生方波个数 占空比&#xff1a;在一个方波内&#xff0c;高电平占用的百分比 宽度调制&#xff1a;占…

开发知识点-uniapp微信小程序-开发指南

uniapp Vue的原型链生命周期函数onLoaduni.chooseLocationgetCurrentPages美团外卖微信小程序开发uniapp-美团外卖微信小程序开发P1 成果展示P2外卖小程序后端&#xff0c;学习给小程序写http接口P3 主界面配置P4 首页组件拆分P13 外卖列表布局筛选组件商家 布局测试数据创建样…

莹莹API管理系统源码附带两套模板

这是一个API后台管理系统的源码&#xff0c;可以自定义添加接口&#xff0c;并自带两个模板。 环境要求 PHP版本要求高于5.6且低于8.0&#xff0c;已测试通过的版本为7.4。 需要安装PHPSG11加密扩展。 已测试&#xff1a;宝塔/主机亲测成功搭建&#xff01; 安装说明 &am…

Flutter 中数据存储的四种方式

在 Flutter 中&#xff0c;存储是指用于本地和远程存储和管理数据的机制。以下是 Flutter 中不同存储选项的概述和示例。 Shared Preferences&#xff08;本地键值存储&#xff09; Shared Preferences 是一种在本地存储少量数据&#xff08;例如用户首选项或设置&#xff09…

C/C++统计数 2021年12月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析

目录 C/C统计数 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 C/C统计数 2021年12月 C/C编程等级考试一级编程题 一、题目要求 1、编程实现 给定一个数的序列S&#xff0c;以及一个区间[L, R], 求序列…

基于Vue+SpringBoot的大病保险管理系统 开源项目

项目编号&#xff1a; S 031 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S031&#xff0c;文末获取源码。} 项目编号&#xff1a;S031&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统配置维护2.2 系统参保管理2.3 大…

(七)什么是Vite——vite优劣势、命令

vite分享ppt&#xff0c;感兴趣的可以下载&#xff1a; ​​​​​​​Vite分享、原理介绍ppt 什么是vite系列目录&#xff1a; &#xff08;一&#xff09;什么是Vite——vite介绍与使用-CSDN博客 &#xff08;二&#xff09;什么是Vite——Vite 和 Webpack 区别&#xff0…

关于缓存和数据库一致性问题的深入研究

如何保证缓存和数据库一致性&#xff0c;这是一个老生常谈的话题了。 但很多人对这个问题&#xff0c;依旧有很多疑惑&#xff1a; 到底是更新缓存还是删缓存&#xff1f;到底选择先更新数据库&#xff0c;再删除缓存&#xff0c;还是先删除缓存&#xff0c;再更新数据库&…