master分支删除文件_git 创建远程分支和删除 master 分支

.

.

.

.

.

最近需要将不同的客户的代码分开管理,所以需要为这些代码分别创建分支。

目前版本库中分支结构如下:

[yuhuashi@local:Project]$ git branch -a

* master

remotes/origin/HEAD -> origin/master

remotes/origin/masger

remotes/origin/master

其中 master 分支是客户 A 所使用的分支。

其它客户则以 masger 分支为基础版本创建。

大致需求的流程如下:

1.以 masger 分支作为基础为客户 B 创建分支 join。

2.将客户 A 的 master 分支重命名为 work。

修改后的分支应该如下所示:

$ git branch -a

* join

remotes/origin/HEAD -> origin/join

remotes/origin/work

remotes/origin/join

remotes/origin/masger

好了,叙述完了需求,那么就从头开始做起。

1.从远程仓库 clone 代码到本地,并创建本地仓库。

[yuhuashi@local:~]$ git clone ssh://[email protected]/~/proj/Project

Cloning into 'Project'...

[email protected]'s password:

remote: Counting objects: 7981, done.

remote: Compressing objects:100% (5962/5962), done.

remote: Total7981 (delta 2504), reused 6801 (delta 1784)

Receiving objects:100% (7981/7981), 125.27 MiB | 25.29 MiB/s, done.

Resolving deltas:100% (2504/2504), done.

[yuhuashi@local:~]$ cd Project/[yuhuashi@local:Project]$ git branch-a*master

remotes/origin/HEAD -> origin/master

remotes/origin/masger

remotes/origin/master

[yuhuashi@local:Project]$

解释:通过 git branch -a 命令可以看到当前的分支结构。

2.创建一个空分支

[yuhuashi@local:Project]$ git checkout --orphan joinSwitched to a new branch'join'[yuhuashi@local:Project]$ gitrm -rf .rm '.gitignore'

rm 'Project.xcodeproj/project.pbxproj'

rm 'Project/Base.lproj/LaunchScreen.xib'

rm 'Project/Base.lproj/Main.storyboard'......

[yuhuashi@local:Project]$

[yuhuashi@local:Project]$ git branch -a

master

remotes/origin/HEAD -> origin/master

remotes/origin/masger

remotes/origin/master

[yuhuashi@local:Project]$

解释:git checkout 的时候指定 --orphan 参数可以创建一个不包含历史 log 的分支,如果使用 git branch join 会创建一个与当前分支一模一样的叫做 join 的分支,会带着 master 分支的 log。

分支创建好之后再使用 git rm -rf . 来删除当前分支下所有被跟踪的文件。

当然,使用 checkout 创建的这个空分支使用 git branch -a 命令是看不见的,必须 commit 一次才能看见。

但是直接在这个空分支中 commit 也是不可以的(如下所示),必须在这里做一些修改才能提交。

[yuhuashi@local:Project]$ git add .

[yuhuashi@local:Project]$ git status

# On branchjoin#

# Initial commit

#

nothing to commit (create/copy files and use "git add"to track)

[yuhuashi@local:Project]$ git commit-m "Initial commit"# On branchjoin#

# Initial commit

#

nothing to commit (create/copy files and use "git add"to track)

[yuhuashi@local:Project]$

既然 join 分支是为了客户 B 创建的,那么我们就把客户 B 的工程拷贝到当前文件夹中。

[yuhuashi@local:~]$ cd ..

[yuhuashi@local:Project]$ git clonessh://[email protected]/~/proj/Project b_join

Cloning into 'Project'...

[email protected]'s password:

remote: Counting objects: 8001, done.

remote: Compressing objects:100% (5722/5722), done.

remote: Total8001 (delta 2517), reused 7309 (delta 2042)

Receiving objects:100% (8001/8001), 125.28 MiB | 29.03 MiB/s, done.

Resolving deltas:100% (2517/2517), done.

[yuhuashi@local:~]$ cd b_join

[yuhuashi@local:b_join]$ git checkout-b join origin/masger

Branchjoin set up to track remote branch joinfrom origin.

Switched to a new branch'join'[yuhuashi@local:b_join]$

我们随便找一个目录,然后把工程重新 clone 下来,这样做的目的是先把客户 B 的代码下载下来,以便拷贝到我们刚刚为客户 B 创建的 join 分支中。

[yuhuashi@local:b_join]$ cp -r ./*../Project/

[yuhuashi@local:b_join]$ cd ../Project

复制的时候要注意,来源路径要写成“目录名/*”,就像上面的栗子中写成了 ./*,这样不会把 ~/b_join/.git 文件夹拷贝到 ~/Project/ 目录下,覆盖掉我们的 .git 目录。

现在我们新建的 join 分支下已经有客户 B 的代码了,那么就可以提交这个分支了。

[yuhuashi@local:Project]$ git status

# On branchjoin#

# Initial commit

#

# Untracked files:

# (use"git add ..." to include inwhat will be committed)

#

# Project.xcodeproj/# Project/# ProjectTests/nothing added to commit but untracked files present (use"git add"to track)

[yuhuashi@local:Project]$ git add .

[yuhuashi@local:Project]$ git commit-m "Initial commit"[join (root-commit) cf9b8d6] Initial commit6771 files changed, 1420915 insertions(+)

create mode100644 Project.xcodeproj/project.pbxproj

create mode100644 Project/Base.lproj/LaunchScreen.xib

create mode100644 Project/Base.lproj/Main.storyboard

......

[yuhuashi@local:Project]$ git branch-a* joinmaster

remotes/origin/HEAD -> origin/master

remotes/origin/masger

remotes/origin/master

[yuhuashi@local:Project]$

git commit 之后再使用 git branch -a 就可以看到我们创建的 join 分支了,而且使用 git log 命令查看会发现并没有带有 master 分支的历史记录。

3.创建远程分支

此时这个 join 分支还只是在我们的本地库中,我们得把它推送到远程库上去,这样别人才能使用它。

[yuhuashi@local:Project]$ git push origin HEAD:[email protected]'s password:

Counting objects: 6866, done.

Delta compression using up to8threads.

Compressing objects:100% (4910/4910), done.

Writing objects:100% (6866/6866), 119.69 MiB | 14.84 MiB/s, done.

Total6866 (delta 1751), reused 6811 (delta 1743)

Tossh://[email protected]/~/proj/Project

* [new branch] HEAD -> join[11:12:30 yuhuashi@local:Project]$ git branch -a* joinmaster

remotes/origin/HEAD -> origin/master

remotes/origin/joinremotes/origin/masger

remotes/origin/master

[yuhuashi@local:Project]$

其实创建远程分支就是把本地分支推送到远程即可,也就是执行 git push origin HEAD:join,这样本地的 join 分支就被推送到 origin/join 了。

好了,到了这一步,我们为客户 B 创建干净分支的目的就完成了,接下来为客户 A 把 master 分支重命名为 work。

4.重命名远程分支

重命名远程分支就是先删除远程分支,然后重命名本地分支,最后再将本地分支推送到远程库。

一般的做法如下:

删除远程分支。这种方式是推送一个空分支到远程库,其实就是删除远程分支:

git push origin :masger

重命名本地分支:

git branch -m masger develop

将本地分支推送到远程库:

git push origin HEAD:develop

但是LZ这种情况不太一样,因为要重命名的是 master 分支,master 分支是默认分支,并且别人在访问我们的库的时候默认显示的是这个分支的内容,所以我们不能直接删除,否则会收到一个异常:

$> git push origin :master

remote: error: By default, deleting the current branch is denied, because the next

remote: error: 'git clone' won't result in any file checked out, causing confusion.

remote: error:

remote: error: You can set 'receive.denyDeleteCurrent' configuration variable to

remote: error: 'warn' or 'ignore' in the remote repository to allow deleting the

remote: error: current branch, with or without a warning message.

remote: error:

remote: error: To squelch this message, you can set it to 'refuse'.

remote: error: refusing to delete the current branch: refs/heads/gitcafe-pages

To [email protected]:ranmocy/ranmocy.git

! [remote rejected] gitcafe-pages (deletion of the current branch prohibited)

error: failed to push some refs to '[email protected]:ranmocy/ranmocy.git'

$>

解决办法就是修改默认分支为其它分支。但是应该怎么修改远程库的默认分支呢?我们在本地操作的时候修改的都是本地分支,无法影响到远程,而且搜索出来的文章里都是用了类似 git@osc 这样的代码托管网站,可以直接在 web 页面上修改远程默认分支,如下图所示:

那么我们自己的远程仓库应该怎样修改默认分支呢?

其实对于你本地的库来说,被你 clone 的那个库就是远程库,而如果你在远程库里直接操作,那不就相当于是修改远程库的本地分支了吗?

于是你得先登录到远程库的服务器上,然后在里面修改它的本地分支。

# 登录到远程 git 库所在的服务器

[yuhuashi@local:Project]$ssh [email protected]# 进入远程 git 库所在的目录

[yuhuashi@local:Project]$ cd proj/Project

# 可以看到,我们的join分支已经创建成功了,并且当前是在 master 分支上。而且可以看出来我们前面的猜测没有错,在本地库看到的远程分支,其实就是远程库的本地分支。

[yuhuashi@local:Project]$ git branch-ajoinmasger*master

# 那么就把远程库的本地分支切换成其它分支吧。哎,为何说这个操作只能在一个工作树中执行呢?

[yuhuashi@local:Project]$ git checkoutjoinfatal: This operation must be runina work tree

# 原来这个远程库只有 git-dir,没有 wrok-tree。

# git-dir 就是 git 进行版本控制的工作空间,存放一些只有 git 才看得懂的文件,一般是 .git 文件夹,只不过 LZ 这个文件夹的名字不叫做 .git,而是与工程同名。

# work-tree 就是我们平时工作使用的目录,也就是被 git 所控制的目录,也就是某一个分支中的内容,里面是我们自己保存在 git 上的文件。一般是 .git 文件夹的上一级目录。

# git pull、checkout 等这些命令只能在 work-tree 中使用,而不能在 git-dir 中使用,因为它们都是用来管理 work-tree 的工具。

[yuhuashi@local:Project]$lsbranches config description HEAD hooksinfoobjects refs

# 知道了什么原因,那么我们就创建一个临时的 work-tree 目录,用来切换分支。

[yuhuashi@local:Project]$ cd ..

[yuhuashi@local:proj]$mkdirtmp

# 前面说过了,一般情况下 work-tree 和 git-dir 是放在一起的,也就是 work-tree 是我们的工程目录,git-dir 是一个叫做 .git 的文件夹作为我们工程文件夹的子目录。

# 其实 git 也提供了两个命令来分别指定当前这条命令是在哪个 git-dir 和 work-tree 上执行,这样就可以让 git 命令运行在 git-dri 与 work-tree 不在一起的情形了。

[yuhuashi@local:proj]$ git--git-dir=./Project --work-tree=./tmp checkout joinChecking out files:100% (6771/6771), done.

Switched to branch'join'[yuhuashi@local:proj]$ cd Project/# OK,分支已经成功切换过去了

[yuhuashi@local:Project]$ git branch-a* joinmasger

master

[yuhuashi@local:proj]$rm -rf tmp

[yuhuashi@local:proj]$ exit

[yuhuashi@local:Project]$

现在远程默认分支已经切换成功了,我们有两种方式继续为客户 A 创建它的 work 分支,一种就是前面第四步所说的:删掉远程分支、重命名本地分支、推送到远程分支。

另一种方法就是以当前 master 分支为基准创建一个一模一样的分支 work,然后删掉本地的 master 分支和远程的 origin/master 分支,然后把 work 分支推送到远程。

LZ选择了第二种方式,为什么呢?因为想尝试一下删除 master 分支的方式 :)

其实删除 master 分支与删除其它远程分支的方式基本相同,唯一不同的一点上面已经讲过了,就是在删除之前要修改一下远程库的默认分支。

好了,看看 LZ 是怎么为用户 A 创建 work 分支的吧。

(1) 创建新分支 work

[yuhuashi@local:Project]$ git branch -a* joinmaster

remotes/origin/HEAD -> origin/master

remotes/origin/joinremotes/origin/masger

remotes/origin/master

[yuhuashi@local:Project]$ git checkout master

Branch master set up to track remote branch master from origin.

Switched to a new branch'master'[yuhuashi@local:Project]$ git branch-ajoin

*master

remotes/origin/HEAD -> origin/master

remotes/origin/joinremotes/origin/masger

remotes/origin/master

# 用这种方式创建分支 work,会保留 master 分支的所有 log,但是不会自动切换分支到 work,所以我们需要手动切换。

[yuhuashi@local:Project]$ git branch work

[yuhuashi@local:Project]$ git checkout work

Switched to branch'work'[yuhuashi@local:Project]$

(2)删除本地 master 分支

[yuhuashi@local:Project]$ git branch -D master

Deleted branch master (was 0981e55).

[yuhuashi@local:Project]$

(3)删除远程 master 分支

[yuhuashi@local:Project]$ git push origin :master

[email protected]'s password:

To ssh://[email protected]/~/proj/Project

-[deleted] master

[yuhuashi@local:Project]$ git branch-a*cruisejoinremotes/origin/HEAD -> origin/master

remotes/origin/joinremotes/origin/masger

[yuhuashi@local:Project]$

可以看到,经过我们前面修改了远程的默认分支之后,现在可以直接删掉远程的 master 分支了。

(4)最后一步,将本地 work 分支推送到远程库。

[yuhuashi@local:Project]$ git push origin HEAD:work

[email protected]'s password:

Counting objects: 7172, done.

Delta compression using up to8threads.

Compressing objects:100% (4924/4924), done.

Writing objects:100% (7115/7115), 123.00 MiB | 15.07 MiB/s, done.

Total7115 (delta 2007), reused 7074 (delta 1970)

Tossh://[email protected]/~/proj/Project

* [new branch] HEAD ->work

[ yuhuashi@local:Project]$ git branch-a*cruisejoinremotes/origin/HEAD -> origin/master

remotes/origin/workremotes/origin/joinremotes/origin/masger

[yuhuashi@local:Project]$

使用 git branch -a 可以看到,work 分支已经成功在远程库上创建了。

最后再看一下远程库的状态:

[yuhuashi@local:Project]$ git remote show origin

[email protected]'s password:

*remote origin

Fetch URL:ssh://[email protected]/~/proj/Project

Push URL: ssh://[email protected]/~/proj/Project

HEAD branch: join # 这里表明远程库的默认分支已经是 join 了Remote branches:

work trackedjointracked

masger tracked

Local refs configuredfor 'git push':

cruise pushes to work (up todate)join pushes to join (up to date)

[yuhuashi@local:Project]$ git branch-a*cruisejoinremotes/origin/HEAD -> origin/master # 这里指向的分支不应该是 origin/master,而应该是 origin/join 才对。

remotes/origin/cruise

remotes/origin/joinremotes/origin/masger

[yuhuashi@local:Project]$

可能是因为这个库的分支已经被修改,而我们本地库还有一些 git 数据没有与远程库同步,LZ 目前没有找到同步的办法,所以我们先删掉这个本地库,重新从远程库 clone 一份。

[yuhuashi@local:Project]$ cd ..

[yuhuashi@local:~]$ rm -rf Project/[yuhuashi@local:~]$ git clone ssh://[email protected]/~/proj/Project

Cloning into 'Project'...

[email protected]'s password:

remote: Counting objects: 8001, done.

remote: Compressing objects:100% (5722/5722), done.

remote: Total8001 (delta 2517), reused 7309 (delta 2042)

Receiving objects:100% (8001/8001), 125.28 MiB | 29.03 MiB/s, done.

Resolving deltas:100% (2517/2517), done.

[yuhuashi@local:~]$ cd Project/[yuhuashi@local:Project]$ git branch-a* joinremotes/origin/HEAD -> origin/joinremotes/origin/cruise

remotes/origin/joinremotes/origin/masger

[yuhuashi@local:Project]$ git pull

[email protected]'s password:

Already up-to-date.

[yuhuashi@local:Project]$ git checkout-b work origin/work

Branch work set up to track remote branch work from origin.

Switched to a new branch'work'[yuhuashi@local:Project]$ git pull

[email protected]'s password:

Already up-to-date.

[yuhuashi@local:Project]$

从上面的流程可知,由于 join 已经是远程库的默认分支,所以我们 clone 了远程库之后,git 已经帮助我们创建好 join 本地分支了。

而且重新下载的代码中,origin/HEAD 已经可以正常指向 origin/join 分支了。

参考文献:

你可能感兴趣的:(master分支删除文件)