仅将更改应用于git分支中的新文件或更新文件

仅将更改应用于git分支中的新文件或更新文件,git,Git,我们正在管理一个分支存根,它是master的精简版本(少了几百个文件)。是否有一种机制(或甚至黑客…)允许从主服务器中提取更新,但忽略修剪后的分支存根中没有的文件 其意图类似于 git checkout stubs git pull origin master --update-or-add-only # This does not exist 其中,——仅更新或添加将由实际逻辑替换。或者更可能是一系列git命令 请注意,这个名称相似的问题有完全不同的用途(忽略某些本地文件) Upd

我们正在管理一个分支存根,它是
master
的精简版本(少了几百个文件)。是否有一种机制(或甚至黑客…)允许从主服务器中提取更新,但忽略修剪后的分支存根中没有的文件

其意图类似于

  git checkout stubs
  git pull origin master --update-or-add-only  # This does not exist
其中,
——仅更新或添加
将由实际逻辑替换。或者更可能是一系列git命令

请注意,这个名称相似的问题有完全不同的用途(忽略某些本地文件)

Update看来
git
不太可能直接支持这样的东西。我正在研究一种混合方法,即通过只查找新条目和修改条目的脚本来选择单个文件

注意:我们还需要将存根中的更改推回到主存根中。同样,只有通过查看最近的git提交并找到哪些文件是新的或修改的,然后使用bash脚本将它们直接从存根的本地克隆复制到master的本地克隆,才有可能实现这一点。

首先,让我们从这个问题中退出,因为退出是一个麻烦:
git pull
意味着,大致来说,运行
git fetch
,然后运行
git merge
。你关心的是合并

Update看来
git
不太可能直接支持这样的东西。我正在研究一种混合方法,即通过只查找新条目和修改条目的脚本来选择单个文件

让我们回到基础:Git通过对每个文件进行完整快照来实现版本控制。这些都在提交中。提交被编号,带有大而难看的散列ID。每个提交都有两部分:快照和一些元数据。元数据显示提交人、提交时间等,并包含其父提交的数量

现在再看看你的问题:你想要新文件和修改过的文件。独立的提交没有新文件。它没有修改过的文件。它没有删除的文件。它只有文件:它只是一个快照。通过将快照与其他快照进行比较,可以发现一些内容是“新的”或“修改的”

我们应该将哪个快照与其他快照进行比较?这是解决问题的关键:您必须选择正确的快照集,并指导Git进行正确的比较。你想要一次比较吗?你想要很多比较吗?您希望在何时完成哪些比较?您希望如何处理每个比较的结果

认识到这一点,再看看
gitmerge
本身是如何操作的,就会告诉您
gitmerge
是否有用。了解这一点,并了解
git cherry-pick
的工作原理,将告诉您
git cherry-pick
是否有用。或者,也许您应该简单地编写自己的工具—一个调用各种Git管道命令1的脚本,该命令将执行您想要执行的操作


1Git将其命令分为陶瓷或面向用户的命令,而不是管道命令。这些通常是用于执行某些特定任务的工具,但这些命令通常提供选项和用户配置。例如,
git pull
运行两个git命令,但是一些用户希望第二个命令是
git-rebase
而不是
git-merge
,因此您可以将
git-pull
配置为运行
git-rebase
而不是
git-merge
。这反过来意味着,如果您100%确定希望在某些脚本中运行
git-fetch
,然后运行
git-merge
,则不应该使用
git-pull
,因为它可能会运行
git-rebase

Git试图划分这些代码的尝试并没有完全成功,但是一些命令,例如
Git for each ref
Git rev list
,肯定不是面向最终用户的,而其他命令,如
Git log
Git diff
则是或试图是。
git diff
命令有多个管道命令,它们实现了不同的部分:
git diff index
git diff树
git diff文件
。这些都不能读取用户配置。
gitdiff
cerial命令确实读取用户配置。因此,在脚本中,通常需要确定要使用哪个管道命令,以免脚本因用户配置而中断


git合并
Merge是一个庞大而复杂的命令,但是如果我们忽略各种选项,例如
--squash
,以及边缘情况,例如当
git Merge
执行快进而不是合并时,它在大多数情况下都相对简单:

  • 合并操作进行两次提交:当前提交(位于当前分支尖端)和其他提交(位于其他分支尖端)

  • Merge使用提交图来标识合并基提交。这是最常见的提交:在两个分支上的所有提交中,有一个是“最佳”的。(从技术上讲,这是由提交图中提交的父/子关系形成的DAG的最大值。)

  • “合并”现在执行的不是一个差异,而是两个差异。这两个差异将合并基础的公共祖先与两个分支提示提交的每个分支进行比较:

    这里我们使用commit
    T
    ,这是我们的樱桃精选目标,所有这些都在我们的工作树中签出,我们已经准备好进行工作。但是我们现在想做的工作已经完成了,在commit
    C
    中,父
    P
    的子项。这是什么意思?这意味着,如果我们将父级
    P
    中的快照与子级
    C
    中的快照进行比较,我们将看到我们希望对目标快照
    T
    所做的更改

    因此,我们需要一个从
    p
    C
    的差值。吉特能肯定吗
              I--J   <-- current-branch (HEAD)
             /
    ...--G--H
             \
              K--L   <-- their-branch
    
    ...--o--o--P--C--o--o--...   <-- some-branch
      ...
        ...--o--T   <-- current-branch (HEAD)
    
    ...--o--o--P--C--o--o--...   <-- some-branch
      ...
        ...--o--T--C'   <-- current-branch (HEAD)
    
    git diff <hash-of-P> <hash-of-C>
    
    git checkout stubs
    git pull origin master --update-or-add-only  # This does not exist
    
    git checkout stubs^0   # do the full merge as a throwaway
    git merge master       # 
    git checkout stubs     # now do a handroll merge and take what you want
    git merge -s ours --no-commit master
    git ls-files | xargs -r git checkout @{1} --