0

我已经在使用 PVCS 控制版本,但我即将开始一个新项目,并希望迁移到 Git/SVN,并保持与我相同的结构。

代码是C,它的结构使得每个C“对象”都有自己的标签,其中只有它的C文件和需要编译的H文件。

在 Git/SVN 中是否可以从主干创建一个分支,该分支仅包含该“对象”编译、制作标记并将更改合并到主干所需的文件?

我尝试过 Git,但每次创建分支时,我都会拥有所有文件,包括来自其他“对象”的 C 和 H 文件,这些“对象”是我不需要的。

我不知道是否有另一个 VCS 允许创建这些部分标签。

4

3 回答 3

1

PVCS似乎是面向文件的(如 CVS 或 RCS),具有集中存储(如 CVS)和锁定(也如 CVS)。

SVN 是面向提交(和集中)的,但将分支视为文件子树,具有合并模型而不是锁定模型(尽管实际上 SVN 也提供文件锁定)。在某些情况下,这可能与您使用标签的方式兼容。但它可能不会:如果您对单个文件进行不同的标记,尽管它们位于相同的文件系统位置,例如,dir/sub/file1.c具有标记 A 和 B,而dir/sub/file2.c具有完全不同的标记 D 和 E,那么这也不会很好地配合使用。

Git 和其他现代 VCS 是分布式的,而不是集中式的,并且是面向提交的。当系统是分布式的时,锁定文件的整个概念几乎就是干杯:没有中央机构声明谁拥有锁定。所以这些都使用合并模型。此外,Git 没有主干的概念:分支都是平等的——或者更准确地说,分支根本没有任何意义。在 Git 中重要的是提交图,分支名称实际上是一个补充技巧,以记住如何通过图工作。

(将这一点与可达性的概念相结合,为 Git 提供了丢弃不需要的对象的能力:与其他一些现代的面向图形的版本控制系统不同,提交并不比任何其他内部对象更特别。委婉地说,这可能有点令人迷惑:在其他面向提交的 VCS 中,一旦提交,它就会永久附加到单个分支上,并且您始终可以在该分支中找到它。因此 Git 比 Mercurial 更具有飞跃性。)

任何时候你有一个面向文件的版本控制系统,很容易挑选出特定的文件,因为这就是 VCS 在下面的工作方式。一旦你进入一个提交模型,“工作区”(无论它在那个特定的 VCS 中被调用什么——Git 使用短语工作树工作目录或任何类似的东西)必须与特定的提交匹配,因为你'如果没有获得 V 版本fileX.c,您将获得构成 V 版本的所有文件。理论上,可以将其与稀疏签出和多个工作区相结合,以便工作区 1 具有稀疏提取的 V1 版本file1.c,工作区2有稀疏提取的V2版本file2.c, 等等; 但你会一直在和模特打架。这可能不是一个好主意。

最后,我认为除非你坚持使用面向文件的 VCS,否则你将不得不改变你的工作流程。

于 2019-04-02T15:53:36.413 回答
0

我无法详细说明 Subversion 将如何处理这个问题。真的 git 和 subversion 是完全不同的问题。我通常可以说我不相信颠覆分支是如何工作的。

我可以肯定地说,这不是 git 分支的工作方式。根据其他答案,您可以将某些东西组合在一起以近似该行为,但我建议不要这样做。迟早会惹上麻烦。

如果您想单独跟踪和编译文件集,则应将它们保存在单独的存储库中,并可能与将它们视为子模块的“父存储库”放在一起。

更一般地说,“切换工具,但保留当前工具的结构”的目标不是很现实。每个源代码控制工具都有自己的项目模型及其内容和历史。如果您喜欢现有的结构,您可能希望继续使用现有的工具。如果您拥有的工具不能正常工作,那可能是该工具使用的结构的症状。

于 2019-04-02T10:54:54.673 回答
0

尽管您对 Git 分支的理解有些混乱,但我想这可能是可行的。

首先,关于分支:在 Git 中,它们只是对他们最后一次提交的引用(实际上,分支是一个文件,其中只有一个提交哈希)。

Git、PVCS 和 SVN 都以非常不同的方式工作。

在 Git 中,如果您想将每个分支的文件分开,这是可能的(尽管不常见)。创建基础分支的建议如下:

创建您的 git 存储库:

ghislain@linux (1): /tmp/example (master) ✔
> git init .
Initialized empty Git repository in /tmp/example/.git/

创建您的文件(尽管您可能已经拥有它们):

ghislain@linux (1): /tmp/example (master #) ✔
> touch foo.c foo.h bar.c bar.h

进行初始提交(它将作为所有分支的基础):

ghislain@linux (1): /tmp/example (master #) ✔
> touch README.md
ghislain@linux (1): /tmp/example (master #) ✔
> git add README.md && git commit -m 'Initial commit'
[master (root-commit) a9a05f3] Initial commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README.md

使用相关文件为每个文件类型创建一个分支:

ghislain@linux (1): /tmp/example (master) ✔
> git checkout -b files-foo master
Switched to a new branch 'files-foo'
ghislain@linux (1): /tmp/example (files-foo) ✔
> git add foo.*
ghislain@linux (1): /tmp/example (files-foo +) ✔
> git commit -m 'foo added'
[files-foo 558cdc6] foo added
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 foo.c
 create mode 100644 foo.h

对上述文件进行一些修改、更新和工作:

ghislain@linux (1): /tmp/example (files-foo) ✔
> vim foo.h
ghislain@linux (1): /tmp/example (files-foo *) ✔
> git add foo.h 
ghislain@linux (1): /tmp/example (files-foo +) ✔
> git commit -m 'foo.h updated'
[files-foo 9565594] foo.h updated
 1 file changed, 1 insertion(+)

对其他文件执行相同操作:

ghislain@linux (1): /tmp/example (master) ✔
> git checkout -b files-bar master
Switched to a new branch 'files-bar'
ghislain@linux (1): /tmp/example (files-bar) ✔
> git add bar.*
ghislain@linux (1): /tmp/example (files-bar +) ✔
> git commit -m 'bar files added'
[files-bar 9f78382] bar files added
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 bar.c
 create mode 100644 bar.h

您的提交日志最终将如下所示,每个文件“类型”有一个分支:

ghislain@linux (1): /tmp/example (files-bar) ✔
> git log --graph --oneline --all
* 9f78382 (HEAD -> files-bar) bar files added
| * 9565594 (files-foo) foo.h updated
| * 558cdc6 foo added
|/  
* a9a05f3 (master) Initial commit

当你想处理一组文件时,你需要在git checkout <related-branch>那里提交。

但是,如果您想要一些交叉引用或共同工作,它可能最终会变得很棘手。对于后者,您必须提交master并在其上重新设置分支(如果您想保持日志清洁)。

总而言之,它可以工作,但最终管理起来可能非常麻烦。我不知道您的项目是如何工作的,但是将所有人放在一起并使用可能更经典的分支工作流程可能会更简单,尤其是如果您是 Git 新手。

于 2019-04-02T10:36:38.913 回答