1. 远程仓库操作
申请到了 Git 远程仓库的帐号并创建了一个空的远程仓库现在我们就可以结合本地的仓库与远程仓库一起协同工作了,模拟多人协同开发,这里我们全部使用命令完成。
1.1 常用操作指令
代码语言:javascript复制 # 下载远程仓库的所有变动
$ git fetch [remote]
# 显示所有远程仓库
$ git remote -v
# 显示某个远程仓库的信息
$ git remote show [remote]
# 增加一个新的远程仓库,并命名
$ git remote add [简称] [url]
# 例如:git remote add gitStudy git@gitee.com:hu-yuyang/gitStudy.git
# 取回远程仓库的变化,并与本地分支合并
$ git pull [remote] [branch]
# 上传本地指定分支到远程仓库
$ git push [remote] [branch]
# 强行推送当前分支到远程仓库,即使有冲突
$ git push [remote] --force
# 推送所有分支到远程仓库
$ git push [remote] --all
#简单查看远程---所有仓库
git remote (只能查看远程仓库的名字)
#查看单个仓库
git remote show [remote-branch-name]
#新建远程仓库
git remote add [branchname] [url]
#修改远程仓库
git remote rename [oldname] [newname]
#删除远程仓库
git remote rm [remote-name]
#获取远程仓库数据
git fetch [remote-name] (获取仓库所有更新,但不自动合并当前分支)
git pull (获取仓库所有更新,并自动合并到当前分支)
#上传数据,如git push origin master
git push [remote-name] [branch]
□ git clone
代码语言:javascript复制 # 正常克隆
$ git clone <版本库的网址>
# 克隆,并对克隆下来的版本库重命名
$ git clone <版本库的网址> <本地目录名>
# 克隆,并对远程仓库起名字
git clone -o <远程仓库简称(默认是origin)> <版本库的网址>
远程操作的第一步,通常是从远程仓库克隆一个版本库,这时就要用到git clone
命令。
$ git clone <版本库的网址>
# 例如克隆我刚创建的gitStudy01远程仓库
$ git clone git@gitee.com:hu-yuyang/gitStudy01.git
Cloning into 'gitStudy01'...
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (4/4), done.
$ git clone git@gitee.com:hu-yuyang/gitStudy02.git
Cloning into 'gitStudy02.git'...
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (4/4), done.
该命令会在本地仓库生成一个目录,与远程仓库的版本库同名。
如果要指定不同的目录名,可以将目录名作为git clone
命令的第二个参数。
$ git clone <版本库的网址> <本地目录名>
# 例如把远程仓库gitStudy 克隆到本地并改名为 git_test030
$ git clone git@gitee.com:hu-yuyang/gitStudy.git git_test030
克隆版本库的时候,所使用的远程仓库自动被 Git 命名为origin
。
如果想用其他的仓库名,需要用git clone
命令的-o
选项指定。
$ git clone -o gitTest git@gitee.com:hu-yuyang/gitStudy01.git
Cloning into 'gitStudy'...
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (4/4), done.
# 上面命令表示,克隆的时候,指定远程仓库(远程仓库)叫做 gitTest。
$ cd gitStudy
$ git remote
gitTest
git clone
支持多种协议,除了 HTTP(s) 以外,还支持 SSH、Git、本地文件协议等,下面是一些例子。
$ git clone http[s]://example.com/path/to/repo.git/
$ git clone ssh://example.com/path/to/repo.git/
$ git clone git://example.com/path/to/repo.git/
$ git clone /opt/git/project.git
$ git clone file:///opt/git/project.git
$ git clone ftp[s]://example.com/path/to/repo.git/
$ git clone rsync://example.com/path/to/repo.git/
□ git remote
代码语言:javascript复制 # 显示所有远程仓库
$ git remote
# -v > 查看远程仓库的网址
$ git remote -v
# 显示某个远程仓库的信息 [远程仓库简称]
$ git remote show [remote-name]
# 增加一个新的远程仓库,并命名
$ git remote add [简称] [url]
# $ git remote add hyy01 git@gitee.com:hu-yuyang/gitStudy01.git
为了便于管理,Git 要求每个远程仓库都必须指定一个仓库名。
git remote
命令就用于管理仓库名。
不带选项的时候,git remote
命令列出所有远程仓库。
# 初始化本地文件夹
$ git init
# 连接一个新的远程仓库,并命名为hyy01
$ git remote add hyy01 git@gitee.com:hu-yuyang/gitStudy01.git
# 连接另一个远程仓库,并命名为hyy02
$ git remote add hyy02 git@gitee.com:hu-yuyang/gitStudy02.git
# 用于添加远程仓库,并命名
$ git remote add <remote-name> <网址>
代码语言:javascript复制 $ git remote
hyy01
hyy02
使用-v
选项,可以查看远程仓库的网址。
$ git remote -v
hyy01 git@gitee.com:hu-yuyang/gitStudy01.git (fetch)
hyy01 git@gitee.com:hu-yuyang/gitStudy01.git (push)
hyy02 git@gitee.com:hu-yuyang/gitStudy02.git (fetch)
hyy02 git@gitee.com:hu-yuyang/gitStudy02.git (push)
上面命令表示,当前有两台远程仓库,叫做 hyy01和hyy02,以及它的网址。
克隆版本库的时候,所使用的远程仓库自动被 Git 命名为origin
。
如果想用其他的仓库名,需要用git clone
命令的-o
选项指定。
$ git clone -o gitTest git@gitee.com:hu-yuyang/gitStudy.git
Cloning into 'gitStudy'...
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (4/4), done.
# 上面命令表示,克隆的时候,指定远程仓库(远程仓库)叫做 gitTest。
$ cd gitStudy
$ git remote
gitTest
git remote show
命令加上仓库名,可以查看该仓库的详细信息。
$ git remote show <remote-name>
$ git remote show gitTest
* remote gitTest
Fetch URL: git@gitee.com:hu-yuyang/gitStudy.git
Push URL: git@gitee.com:hu-yuyang/gitStudy.git
HEAD branch: master
Remote branch:
master tracked
# 为“git pull”配置的本地分支:
Local branch configured for 'git pull':
# 仓库与远程仓库合并
master merges with remote master
# 为“git push”配置的本地引用:
Local ref configured for 'git push':
# 仓库推送到仓库(最新)
master pushes to master (up to date)
git remote add
命令用于添加远程仓库。
$ git remote add <remote-name> <网址>
$ git remote add gitStudy git@gitee.com:hu-yuyang/gitStudy.git
git remote rm
命令用于删除远程仓库。
$ git remote rm <remote-name>
git remote rm gitStudy
git remote rename
命令用于远程仓库的改名。
$ git remote rename <old-remote-name> <new-remote-name>
$ git remote rename gitStudy gitTest
□ git fetch
代码语言:javascript复制 $ git branch -a # 查看远程分支
$ git branch -r # 查看所有分支
# 拉取最新内容到本地仓库|不是你现在的工作空间(文件夹)
$ git fetch <远程仓库名>
# 合并远程指定分支到当前分支
$ git merge <远程仓库名/branch>
# 取回特定分支的更新,可以指定分支名。
$ git fetch <远程仓库名> <分支名>
# 在远程分支的基础上,使用`git checkout`命令创建一个新的分支。
$ git checkout -b newBrach origin/master
git fetch
远程仓库的最新内容拉到本地(本地仓库而不是你的文件夹),用户在检查了以后决定是否合并到工作本机分支中。
$ git fetch <远程仓库名>
例子:
代码语言:javascript复制# 之前的准备:在gitStudy01文件夹(git clone 拉取的gitStudy01远程仓库|origin)push 了个文件hyy.txt
# 然后回到gitSutdy03文件夹(git remote add 添加的gitStudy01 和gitStudy02仓库|hyy01,hyy02)
$ git fetch hyy01
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 7 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (7/7), 2.07 KiB | 49.00 KiB/s, done.
From gitee.com:hu-yuyang/gitStudy01
* [new branch] master -> hyy01/master # 表示hyy01仓库的master分支
# 合并hyy01/master 到当前分支(也是hyy01/master)
$ git merge hyy01/master
# 查看本地文件夹,可以看到已经拉取过来了
$ ll
total 9
-rw-r--r-- 1 Lenovo 197617 870 Nov 30 21:03 README.en.md
-rw-r--r-- 1 Lenovo 197617 960 Nov 30 21:03 README.md
-rw-r--r-- 1 Lenovo 197617 5 Nov 30 21:03 hyy.txt
git fetch
命令通常用来查看其他人的进程,因为它取回的代码对你本地的开发代码没有影响。
默认情况下,git fetch
取回所有分支(branch)的更新。
如果只想取回特定分支的更新,可以指定分支名。
代码语言:javascript复制$ git fetch <远程仓库名> <分支名>
例子:
代码语言:javascript复制# 准备:在gitStudy02文件夹(git clone 拉取的gitStudy02远程仓库|origin)push 了个文件hyy01.txt
# 然后回到gitSutdy03文件夹(git remote add 添加的gitStudy01 和gitStudy02仓库|hyy01,hyy02)
# 拉取远程仓库hyy02 的master分支
$ git fetch hyy02 master
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (4/4), 2.08 KiB | 54.00 KiB/s, done.
From gitee.com:hu-yuyang/gitStudy02
* branch master -> FETCH_HEAD
* [new branch] master -> hyy02/master
# 致命:拒绝合并不相关的历史记录
$ git merge hyy02/master
fatal: refusing to merge unrelated histories
所取回的更新,在本地仓库上要用 "远程仓库名 / 分支名" 的形式读取。
比如hyy02
仓库的master
,就要用hyy02/master
读取。
git branch
命令的-r
选项,可以用来查看远程分支,-a
选项查看所有分支。
$ git branch -r
hyy01/master
hyy02/master
$ git branch -a
* master
remotes/hyy01/master
remotes/hyy02/master
上面命令表示,本地仓库的当前分支是master
,远程分支是hyy01/master
和hyy02/master
。
取回远程仓库的更新以后,可以在它的基础上,使用git checkout
命令创建一个新的分支。
$ git checkout -b newBrach origin/master
$ git checkout -b dev1 hyy02/master
Switched to a new branch 'dev1'
Branch 'dev1' set up to track remote branch 'master' from 'hyy02'.
上面命令表示,在origin/master
的基础上,创建一个新分支。
此外,也可以使用git merge
命令或者git rebase
命令,在本地分支上合并远程分支。
$ git merge hyy01/master
# 或者
$ git rebase hyy01/master
上面命令表示在当前分支上,合并hyy01/master
。
可以简单的概括为:
git fetch
是将远程仓库的最新内容拉到本地,用户在检查了以后决定是否合并到工作本机分支中。
而git pull
则是将远程仓库的最新内容拉下来后直接合并,
即:git pull = git fetch git merge
,这样可能会产生冲突,需要手动解决。
下面我们来详细了解一下git pull
的用法。
□ git pull
git pull
命令的作用是,取回远程仓库某个分支的更新,再与本地的指定分支合并。
它的完整格式稍稍有点复杂。
代码语言:javascript复制$ git pull <远程仓库名> <远程分支名>:<本地分支名>
比如,取回origin
仓库的next
分支,与本地的master
分支合并,需要写成下面这样。
# 准备:在gitStudy01文件夹(git clone 拉取的gitStudy01远程仓库|origin)push 了个文件hyy03.txt
$ git pull hyy01 master:master
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 2 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (2/2), 266 bytes | 38.00 KiB/s, done.
From gitee.com:hu-yuyang/gitStudy01
23110ae..09e7ddc master -> master
23110ae..09e7ddc master -> hyy01/master
warning: fetch updated the current branch head.
fast-forwarding your working tree from
commit 23110ae39ec598d8f223c4a21d3703ac529f8051.
Already up to date.
$ ll
total 11
-rw-r--r-- 1 Lenovo 197617 870 Nov 30 21:32 README.en.md
-rw-r--r-- 1 Lenovo 197617 960 Nov 30 21:32 README.md
-rw-r--r-- 1 Lenovo 197617 5 Nov 30 21:32 hyy.txt
-rw-r--r-- 1 Lenovo 197617 5 Nov 30 21:32 hyy02.txt
-rw-r--r-- 1 Lenovo 197617 5 Nov 30 21:36 hyy03.txt
如果远程分支是与当前分支合并,则冒号后面的部分可以省略。
代码语言:javascript复制$ git pull hyy01 master
上面命令表示,取回hyy01/master
分支,再与当前分支合并。
实质上,这等同于先做git fetch
,再做git merge
。
在某些场合,Git 会自动在本地分支与远程分支之间,建立一种追踪关系(tracking)。
比如,在
git clone
的时候,所有本地分支默认与远程主机的同名分支,建立追踪关系, 也就是说,本地的master
分支自动 "追踪"origin/master
分支。
Git 也允许手动建立追踪关系。
代码语言:javascript复制git branch --set-upstream-to master origin/next
上面命令指定master
分支追踪origin/next
分支。
如果当前分支与远程分支存在追踪关系,git pull
就可以省略远程分支名。
$ git pull hyy01
上面命令表示,本地的当前分支自动与对应的origin
主机 "追踪分支"(remote-tracking branch)进行合并。
如果当前分支只有一个追踪分支,连远程主机名都可以省略。
代码语言:javascript复制$ git pull
上面命令表示,当前分支自动与唯一一个追踪分支进行合并。
如果合并需要采用 rebase
模式,可以使用--rebase
选项。
$ git pull --rebase <远程主机名> <远程分支名>:<本地分支名>
如果远程主机删除了某个分支,默认情况下,git pull
不会再拉取远程分支的时候,删除对应的本地分支。
这是为了防止,由于其他人操作了远程主机,导致git pull
不知不觉删除了本地分支。
但是,你可以改变这个行为,加上参数 -p
就会在本地删除远程已经删除的分支。
$ git pull -p
# 等同于下面的命令
$ git fetch --prune origin
$ git fetch -p
□ git push
git push
命令用于将本地分支的更新,推送到远程主机。
它的格式与git pull
命令相仿。
$ git push <远程主机名> <本地分支名>:<远程分支名>
注意,分支推送顺序的写法是 <来源地>:< 目的地 >,所以git pull
是 <远程分支>:< 本地分支 >,而git push
是 <本地分支>:< 远程分支 >。
如果省略远程分支名,则表示将本地分支推送与之存在 "追踪关系" 的远程分支(通常两者同名),如果该远程分支不存在,则会被新建。
代码语言:javascript复制# 准备:在gitStuyd03 新建hyy05.txt 并commit到本地仓库
$ git push hyy01 master
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 318 bytes | 318.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [GNK-6.2]
To gitee.com:hu-yuyang/gitStudy01.git
34ba703..3d85904 master -> master
上面命令表示,将本地仓库的master
分支推送到hyy01
远程仓库的master
分支。
如果后者不存在,则会被新建。
如果省略本地分支名,则表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支。
代码语言:javascript复制$ git push origin :master
# 等同于
$ git push origin --delete master
如果当前分支只有一个追踪分支,那么主机名都可以省略。
代码语言:javascript复制$ git push
如果当前分支与多个主机存在追踪关系,则可以使用-u
选项指定一个默认主机,这样后面就可以不加任何参数使用git push
。
$ git push -u hyy01 master
Everything up-to-date
Branch 'master' set up to track remote branch 'master' from 'hyy01'.
上面命令将本地的master
分支推送到hyy
远程仓库,同时指定hyy01
为默认远程仓库,后面就可以不加任何参数使用git push
了。
不带任何参数的git push
,默认只推送当前分支,这叫做 simple 方式。
此外,还有一种 matching 方式,会推送所有有对应的远程分支的本地分支。
Git 2.0 版本之前,默认采用 matching 方法,现在改为默认采用 simple 方式。
如果要修改这个设置,可以采用git config
命令。
$ git config --global push.default matching
# 或者
$ git config --global push.default simple
还有一种情况,就是不管是否存在对应的远程分支,将本地的所有分支都推送到远程主机,这时需要使用--all
选项。
$ git push --all hyy01
上面命令表示,将所有本地分支都推送到hyy01
远程仓库。
如果远程仓库的版本比本地版本更新,推送时 Git 会报错,要求先在本地做git pull
合并差异,然后再推送到远程主机。这时,如果你一定要推送,可以使用--force
选项。
$ git push --force origin
上面命令使用--force
选项,结果导致远程主机上更新的版本被覆盖。
除非你很确定要这样做,否则应该尽量避免使用--force
选项。
最后,git push
不会推送标签(tag),除非使用--tags
选项。
$ git push origin --tags
我正在参与2023腾讯技术创作特训营第二期有奖征文,瓜分万元奖池和键盘手表