我试图将我的SVN存储库转换为GIT存储库。 这个问题是,在SVN中有几个活动分支 不同的软件版本并行维护。 所以SVN设置看起来像这样:
SVN ROOT
|- trunk
|- branches
| |- v1
| |- v2
| |- v3
|- tags
| |- v1
| | |- 0
| | |- 1
| |- v2
...
现在我想创建一个GIT存储库,其中包含每个分支的分支 SVN。创建存储库和移植标记根本不是问题。 我正在做一个
git svn init -s --tags=tags/v1 --tags=tags/v2 <REPO_URL>
# modified .git/config to use tags/v1/* for the tags of the different versions
git svn fetch
在此之后,我根据需要获得了分支机构,并且我可以使用
查看不同的软件版本git checkout -b v1 origin/v1
问题是SVN存储库是旧的,不同的分支都从 trunk 分支出来。但是我的开发需要我修复一个bug v1 ,将其合并到 v2 ,然后 dcommit 将所有内容反馈回SVN。
所以我的问题是什么是获得干净(可合并/可重组)GIT分支的最佳方式?那么工作流程应该如何呢? 我应该为GIT中的每个版本添加一个新分支,让我们说 svn_v1 ,将 v1 重新绑定到此,然后 dcommit 那里?或者什么是将提交返回SVN的最佳方式?
修改:
我已经尝试根据合并上游来修改不同的分支(例如,将 v2 重新定位到 v1 和 trunk 上 v2 )但这搞砸了 我的历史记录,在尝试 dcommit 时,它想要提交我在当前历史记录之上重新提交的所有提交。这会使SVN历史变得混乱,因为这些提交已经在Repo中。
EDIT2:
使问题更加清晰。想象如下历史:
D--E--F v1 K--L--M v2
/ /
A--B--C--G--H--I--J--N trunk
^
|
introduced a bug
由于提交B
引入了错误,所有分支v1
,v2
和trunk
都会受到影响。我的公司的政策现在(在SVN中)在受影响最小的分支(在这种情况下为v1
)中解决此问题,然后通过
分支到trunk
。
工作流如何在GIT中执行相同的操作,以便在SVN中v1
中的提交被标记为合并到v2
?
答案 0 :(得分:2)
听起来你想在v1
中做你的错误修正,然后在提交两者之前在v2
中挑选它。这不是git
术语中的合并或rebase操作。如果您要在v1
中进行更改,然后将其合并到master
,然后将其合并或重新绑定到v2
。
我承认,在你的描述之后,我不太确定问题出在哪里。这听起来更像是一个工作流问题,然后给我一个git-svn问题?如果你的svn分支很好(即,不是一团糟),那么git init
应该以一种你可以像往常一样使用它们的方式转移它们。如果他们已经在svn方面已经退化很多,那么它真的无法“修复”这个混乱。
编辑:回复你的第二次编辑:你描述的内容(在所有分支上分发修补程序/补丁)在git中被称为“cherry-picking”,而不是合并。 git不会(也不需要)跟踪你是否做了樱桃挑选的东西;你只是这样做并完成它。您绝对不希望在您的方案中进行任何合并或重组。
所以,这是你可以做的:
你的情况
D--E--F v1 K--L--M v2
/ /
A--B--C--G--H--I--J--N trunk
^
|
introduced a bug
如果这是您的政策,请修复您的错误并提交v1
。
git checkout v1
# fix bug
git add ; git commit
# note the commit hash you just created, let's call it a1b2c3d4
分发给其他分支机构
git checkout v2
git cherry-pick a1b2c3d4
git checkout trunk
git cherry-pick a1b2c3d4
新情况
D--E--F--a1b2c3d4 v1 K--L--M--abcde123 v2
/ /
A--B--C--G--H-------------I--J--N--bca123123 trunk
^
|
introduced a bug
就是这样。 git cherry-pick
将自动获取该单个提交的diff / patch,将其应用于当前的HEAD,并创建新的提交。 (按设计)“后台”没有任何进展,这是一个非常简单的程序。可能会像往常一样发生冲突,您可能需要手动修复,但git
会告诉您要做的更多或更少。
如果您以后继续常规工作,并合并/重新组合这些分支,git
不需要知道挑选樱桃。这些东西都在你的文件中,它会看到(或没有看到)文本上的差异,运气好的话一切都会好的。
答案 1 :(得分:0)
好的,我终于设法自己解决了这个问题。
我已经分两步解决了这个问题:首先,由于v1
和v2
的代码库很好(构建和工作,两者都修复了已知的错误),因此我可以使用v1
和v2
。我们在v2
中记录了trunk
分支到svn
分支和git
到git-svn
的合并。
现在我可以合并git config svn.pushmergeinfo true
中的分支。然后我在dcommit
文档中找到了这段话:
config key:svn.pushmergeinfo
此选项将导致git-svn尝试在可能的情况下自动填充SVN存储库中的svn:mergeinfo属性。目前,这只能在提交非快进合并时才能完成,其中除第一个之外的所有父级已经被推入SVN。
所以我已启用此配置值
svn
现在,如果发现新的错误,我会将其修复到出现此错误的最低版本,--no-ff
将其修复为dcommit
,然后将其合并到下一个版本中使用svn
选项。如果我现在package vindue;
import javax.swing.*;
/**
*
* @author BE56df
*/
public class Vindue {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
paneler panel = new paneler();
JFrame vindue = new JFrame("NEZ - Evolution Simulator v0.1");
vindue.add(panel);
vindue.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
vindue.setResizable(false);
vindue.pack();
vindue.setVisible(true);
}
}
,package vindue;
import java.awt.*;
import javax.swing.*;
/**
*
* @author BE56df
*/
public class paneler extends javax.swing.JPanel {
/**
* Creates new form paneler
*/
public paneler() {
initComponents();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawLine(0, 0, 750, 550);
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
EvoPanel = new javax.swing.JPanel();
jLabel1 = new javax.swing.JLabel();
jSeparator1 = new javax.swing.JSeparator();
jToggleButton1 = new javax.swing.JToggleButton();
setMaximumSize(new java.awt.Dimension(750, 550));
setMinimumSize(new java.awt.Dimension(750, 550));
setPreferredSize(new java.awt.Dimension(750, 550));
EvoPanel.setBackground(new java.awt.Color(200, 200, 200));
EvoPanel.setMaximumSize(new java.awt.Dimension(550, 550));
EvoPanel.setMinimumSize(new java.awt.Dimension(550, 550));
javax.swing.GroupLayout EvoPanelLayout = new javax.swing.GroupLayout(EvoPanel);
EvoPanel.setLayout(EvoPanelLayout);
EvoPanelLayout.setHorizontalGroup(
EvoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 550, Short.MAX_VALUE)
);
EvoPanelLayout.setVerticalGroup(
EvoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 550, Short.MAX_VALUE)
);
jLabel1.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
jLabel1.setText("Control panel");
jLabel1.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM);
jLabel1.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
jToggleButton1.setText("Auto play");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(EvoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addGap(63, 63, 63)
.addComponent(jLabel1)
.addGap(0, 58, Short.MAX_VALUE))
.addGroup(layout.createSequentialGroup()
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(jSeparator1, javax.swing.GroupLayout.DEFAULT_SIZE, 190, Short.MAX_VALUE)
.addComponent(jToggleButton1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(EvoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jToggleButton1))
);
}// </editor-fold>
// Variables declaration - do not modify
private javax.swing.JPanel EvoPanel;
private javax.swing.JLabel jLabel1;
private javax.swing.JSeparator jSeparator1;
private javax.swing.JToggleButton jToggleButton1;
// End of variables declaration
}
中的mergeinfos会更新,一切正常。