如何在多个不同的分支上工作,我可以在它们之间轻松切换?

时间:2016-06-30 21:54:48

标签: git svn

有没有办法处理同一个文件但是在GIT中的不同功能/分支上?

我确定有办法,但最简单的方法是什么? 我不想隐藏我的更改,因为这很麻烦。

借助SVN,我能够在2个不同的分支上工作,无需任何干预,可以在两个不同的实体之间切换,并且可以在两者之间切换。

5 个答案:

答案 0 :(得分:13)

使用git worktree。

git worktree

Git worktree于2007年在git repo的contrib文件夹下引入,名为new-workdir

git V2.5 中,它被命名为worktree,它允许您在不同的文件夹中拥有相同存储库的多个实例。

例如:

git worktree add <second path>

将在您的计算机上创建另一个文件夹,允许您同时在不同的分支上工作。

如果要删除工作树,请删除该文件夹,然后执行git worktree prune,这将删除工作树引用。

  

<强> prune
  修剪$GIT_DIR/worktrees中的工作树信息。

创建新的工作树

# create new branch inside the worktree folder 
git worktree -b <branch name> <path>

删除工作树

# do your code and once you have done 
# commit, push and now you can delete your folder
rm -rf <path>

# Tell git to remove the workdir copy
git worktree prune

<强>更新 在即将发布的版本(git 2.17 +)中,git worktree delete将作为删除工作树的新命令公开。

列出工作树

enter image description here

如果您稍后使用rebase:

  • 注意:(Since Git 2.7
    您也可以使用git rebase [--no]-autostash

答案 1 :(得分:2)

你好像想要以Subversion的方式去做。我能理解;改变发展习惯可能是一个漫长的过程,而在某种程度上,将工具弯曲到自己的习惯可能会很好;这完全没问题。所以我们走了:

以这种方式思考:使用svn,您有一个大目录树,其中&#34;分支&#34;不是真正的第一类实体,而是(技术上)任意子目录

mystuff/trunk
mystuff/branches/feature1
mystuff/branches/feature2
...
mystuff/tags/1.0   
mystuff/tags/1.1
...

因此,如果您使用它并对它感到满意,那么通过在一个(非git)父级中检出存储库的不同副本,也可以使用git完全相同的解决方案:

mystuff/master
mystuff/master/.git
mystuff/feature1
mystuff/feature1/.git
...

这在概念上与以前完全相同。您始终将不同的存储库保存在各自的分支上。像往常一样,你有一个共同的祖先来推/拉合并(请注意,这可以在本地处理,不需要物理上的远程位置,除非你有一个反正;你也可以/也可以理论上,将master存储库直接用作origin)。

你没有得到,并且永远不会得到git,一次性改变不同的分支(在一个&#34;提交&#34;)。 A&#34;分支&#34;在git中,与Subversion完全不同,就像&#34; commit&#34;在git中是一个根本不同的东西(commit!= revision)。你必须围绕这个,没有任何工具可以帮助你解决这个问题。

一些操作:

  • 创建新功能分支feature2(从master开始):

    mystuff> git clone {URL-or-filesystem-path-of-common-origin-repository} feature2
    mystuff/feature2> git checkout -b feature2
    
  • 将您的工作从分支机构合并到master

    mystuff/feature1> git add ... ; git commit ...
    mystuff/feature1> git push
    
    mystuff/master> git fetch
    mystuff/master> git merge origin/feature1
    

    任何其他合并相同; master分支在技术上与git中的任何其他分支没有什么不同,它只是一个命名约定(如/trunk是Subversion中的命名约定)。

  • 摆脱分支:

    mystuff/feature1> git push origin :feature1      # deletes the branch on the common repository
    mystuff> rm -rf feature1
    

所有这些都占用了比所需更多的HDD存储空间;有一些高级方法可以在本地克隆存储库,重新使用对象存储库。如果这对您很重要,请在评论中告诉我;除非你真的有空间限制,否则我坦率地说不会打扰。

答案 2 :(得分:2)

从我对评论部分的理解:是你想拥有2个不同的&#34;版本&#34;同一个文件。 (正如你在评论中提到的那样,让file.txt有一个&#34; AAAAAAA&#34;在一个上行,&#34; BBBBBBB&#34;在一个上,但不是&#34; AAAA&#34;)。 / p>

这可以通过非常容易的分支来实现。

在开始工作之前,你将会#34;站立&#34;在一个分支上(可能是master)。此时您可以创建一个新分支git checkout -b feature1(此命令创建并切换到分支feature1)。您将在哪里对file.txt进行一些更改。说你会写#A; AAAAAA&#34;。然后,你将不得不提交它。 git commit -a -m "Added the AAAA line"。 如果你现在git checkout master(你回到主人那里)。您的文件WON&#39; T&#34; AAAAA&#34;写在上面,然后您可以对此文件进行其他更改(在此分支或其他分支上)。你可以写&#34; BBBBBBB&#34;到这个文件,你将有2&#34;版本&#34;同一个文件&#34; file.txt&#34;,一个将有&#34; AAAA&#34; (分支feature1上的那个)和master上的另一个将有BBBB。

注意:我创建了一个您最初尚未更改过该文件的方案,但如果您有,则还有通过分支实现此目的的方法。你应该 def 阅读https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging

答案 3 :(得分:1)

  

我不想隐藏我的更改,因为这很麻烦。

你可以做的最好的方法就是在两个分支上编辑文件。

根据您的用例,我们的想法是在您的主分支上建立公共基础,并为每个分支添加一个功能。

答案 4 :(得分:0)

我认为,您的工作流程可能会受到SVN中分支切换速度慢的影响。在Git中,您不必担心这一点 - 新分支的结账将花费一小部分时间(对于非常大的项目可能只需几秒钟)。

对你来说最明智的事情是在单个分支上工作,一旦你做了一些提交,cherry-pick他们到其他分支。示例:(假设您要处理文件f.txt,这在两个分支上都相同)

$ git fetch
$ git checkout branch-1 # assuming remote branches exists already
$ vim f.txt # do some editing
$ git commit -am "f file changed"
$ git checkout branch-2
$ git cherry-pick branch-1 # <- this will pick single last commit from branch-1
                           # and apply it to branch-2

您当然不限于选择最后一次提交 - 您可以通过提交ID,标记来选择,您可以使用~运算符来选择提交祖先等。 你甚至可以通过改变或更好的交互式变基来一次做很多樱桃挑选。

完成工作后,您需要为每个分支执行两次单独的推送(或者您可以将push.default配置选项更改为matching以从所有本地分支执行一次推送。