仅使用一些文件在版本控制中创建标签//分支

Creating tags//branches in version control with only some files

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

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

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

我试过Git,但每次创建分支时,我都拥有所有文件,包括来自其他"objects"的我不需要的C 和H 文件。

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

虽然您对 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

您的提交日志最终将如下所示,每个文件一个分支 "type":

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.

是新手

我无法详细说明 Subversion 将如何处理这个问题; git 和 subversion 真的是完全不同的问题。一般来说,我不相信颠覆分支是这样工作的。

我可以肯定地说,这不是 git 分支机构的工作方式。根据其他答案,您 可以 破解一些东西来近似这种行为,但我建议不要这样做。迟早会出事的

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

更一般地说,"switch tools, but keep the structure from my current tool" 的目标不太现实。每个源代码控制工具都有自己的项目模型及其内容和历史。如果您喜欢现有的结构,您可能希望继续使用现有的工具。如果您拥有的工具不能正常工作,那可能是该工具使用的结构的一个症状。

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

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

Git 和其他现代 VCS 是分布式的,而不是集中式的,并且是面向提交的。当系统是分布式的时,锁定文件的整个概念几乎都是吐司:没有中央机构声明谁拥有锁。所以这些都使用合并模型。 Git 还没有 trunk 的概念: branches are all equal——或者更准确地说,branches 根本没有任何意义. Git 中重要的是 提交图 ,分支名称确实是一个补充技巧,可以帮助您记住如何按照自己的方式工作 through图。

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

任何时候你有一个面向文件的版本控制系统,很容易挑选出特定的文件,因为这就是 VCS 在底层的工作方式。一旦你进入提交模型,"work area"(无论它在那个特定的 VCS 中被调用什么——Git 使用短语 work-treeworking directory 或类似的任何东西)必须与特定的提交匹配,因为你没有得到 fileX.c 的版本 V,你得到的是 all 构成版本 V 的文件。理论上,可以将其与 sparse checkout 和多个工作区结合使用,以便工作区 1 具有版本 V1 的稀疏提取file1.c,工作区2有稀疏提取的V2版本file2.c,以此类推;但你会一直与模型作斗争。这可能不是一个好主意。

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