9

arc help --full | less揭示了这一点graft

  graft revision

      Grafts revision and its dependencies (if any) onto your working tree.

      --force
          Do not run any sanity checks.

      --skip-landed
          Do not try to patch landed/closed diffs.

这对于patch

  patch D12345
  patch --revision revision_id
  patch --diff diff_id
  patch --patch file
  patch --arcbundle bundlefile
      Supports: git, svn, hg
      Apply the changes in a Differential revision, patchfile, or arc
      bundle to the working copy.

      --arcbundle bundlefile
          Apply changes from an arc bundle generated with 'arc export'.

这对我来说很模糊。用“graft”这个词来描述“graft”的意思对我没有多大帮助。


对于那些不知道的人,arc(Arcanist) 是“Phabricator”中的一个命令行工具,它就像一个围绕 Git(甚至是 Mercurial 和 Subversion)的高级包装器,以帮助大型软件项目的开发过程。这里有几个链接:

https://phacility.com/phabricator/

Phabricator 最初是作为 Facebook 的内部工具开发的。[7][8][9] Phabricator 的主要开发人员是 Evan Priestley。[1] Priestley 离开 Facebook,在一家名为 Phacility 的新公司继续 Phabricator 的发展。 [2] https://en.wikipedia.org/wiki/Phabricator

4

2 回答 2

9

2020 年 3 月 19 日更新:

请注意,arc flow并且arc cascade显然不是Phacility 的奥术师主流版本的一部分。相反,它们只是arcanist 的 Uber 分支的一部分例如,可以在此处找到一些arc flow源代码。此外,它也只是 Uber 的 fork 奥术师功能,其部分源代码可在此处找到。要了解如何安装 Uber 的 arcanist 分支,以便在您的常规工作流程中开始使用这些功能(如果不需要,您无需使用任何其他的 arcanist 功能),请跳至此答案的底部arc cascadearc cascade
git


2019 年 1 月的原始答案:

所以,经过一些试验和反复试验,我想我想通了:

两者都在引擎盖下使用,arc graft并完成类似的事情。但是,它们有一些细微的差异,有时会失败,您必须使用标志来代替(更新:或者也许使用标志也可以?)。arc patchgit cherry-pickarc patcharc graft--skip-landedarc patch--skip-dependencies

例子:

# cherry-pick their "D999" "diff" (branch) onto your current branch, while creating 
# a new single branch for you named "arcpatch-D999", skipping dependencies in case 
# they've already landed on the branch (ex: master) you currently have checked out.
arc patch --skip-dependencies D999 

或者

# cherry-pick their "D999" "diff" (branch), *as well as all parent branch(es) it 
# depends on*, onto your current branch, while creating the entire dependency tree 
# of branches for you, exactly as the submitter originally had on their local 
# machine, skipping any commits that have already landed on your local branch 
# (ex: master) you currently have checked out
arc graft --skip-landed D999 

想象一下你的arc flow依赖树只包含“master”分支:

master

但是,一位同事具有以下arc flow依赖关系树:

master                              
└──new_feature_1
   └──new_feature_2 

简而言之:什么是arc flow依赖树?Ans:它是一个树形结构,通过arc flow命令显示,它显示了哪些分支依赖于什么。作为人类,您手动跟踪是一件有点武断的事情,因为您知道一个功能依赖于另一个功能。要建立“依赖关系”,您有两种选择:

  1. arc flow new_branch_name在您当前已签出要成为父级的分支时调用以创建新的子分支,或者:
  2. 使用 git 创建一个新分支,然后将其上游设置为您想要的父级。前任:

    git branch new_branch_name
    git checkout new_branch_name # Or use `git checkout -b new_branch_name` to do both at once
    git branch --set-upstream-to=upstream_branch_name # or `git branch -u upstream_branch_name` for short
    

现在,arc flow将显示您的依赖关系树。这使您可以进行诸如arc cascade从父级到子级之类的事情,这只是在执行从父级到子级的自动递归 git rebases(即:将子级重新设置为父级)。

一边结束。


无论如何,使用上面显示的依赖关系树,您的同事已签出“new_feature_2”,并arc diff供您查看。您转到基于 Web 的“差异化”工具并开始查看更改。但是,您想对其进行测试。这意味着您需要将他们的差异拉到您的本地机器上。您有两个选择:1.arc patch他们的差异(依赖树感知分支)到您的本地 master,或 2.arc graft他们的差异到您的本地 master。

假设他们的差异是“D999”,并且您当前已签出“主”分支,您的命令和生成的依赖树将如下所示:

  1. arc patch D999. 你现在有了这棵树,你新创建的“arcpatch-D999”是他们的“new_feature_2”分支:

    master
    └──arcpatch-D999 
    
  2. arc graft D999. 您现在拥有这棵树,就像他们拥有的一样:

    master                              
    └──new_feature_1
       └──new_feature_2 
    

但是,(我认为,基于我的问题)有时当他们有这样的多代依赖树时,arc patch会失败(给出一个错误,显示“Cherry Pick Failed!”),在这种情况下你必须arc graft使用!但是,如果他们的主人与您的主人不完全相同(几乎可以肯定不会,因为他们可能会在一段时间前拉动他们的主人,而您应该刚刚拉动您的主人以确保您拥有最新的),那么您尝试移植物或补丁将失败。失败很可能与分支历史记录中的某些提交包含已经登陆并存在于您的 master 中的更改有关。解决方案是使用arc graft D999 --skip-landed,这将允许您获取他们的差异并将其拉下,镜像他们的arc flow依赖关系树。在这种情况下,arc patch D999可能会继续失败,直到他们拉出最新的 master 和arc cascade(或 git rebase 两次),然后重新arc diff将他们的更改推送到服务器,此时您可以arc patch D999成功地推送到您的 master 上。但是,由于您不能总是让它们arc cascade立即变基/,所以arc graft D999 --skip-landed现在就完成!让他们arc diff在遇到问题时重新设置基准并重新设置。

然而,一个小问题是,如果你arc grafting 太多,可能会混淆谁制作了哪些分支(你还是其他人?),所以我建议你养成嫁接到你自己命名的新分支的习惯,如以下,仅用于组织:

git checkout master # same as `arc flow master`
git pull origin master # pull latest master
arc flow graft-D999 # create and checkout a new child branch you are calling "graft-D999" (name it appropriately)
arc graft D999 --skip-landed # graft their entire dependency tree onto your branch "graft-D999"

您的依赖关系树现在如下所示:

master                              
└──graft-D999
   └──new_feature_1
      └──new_feature_2 

出色的!尼斯和有组织的。现在您可以查看“new_feature_2”并对其进行编译和测试。但是请注意,“master”和“graft-D999”将是完全相同的分支,但这没关系。

如何安装优步的奥术叉

(如果您想开始使用arc flowarc cascade在您自己的 git 工作流程中使用):

注意:Arcanist 在 Windows(在Windows的git bash 终端的 git 内)、Mac 和 Linux 上运行。我将只介绍 Linux 安装说明。要获得在其他系统中安装的帮助,请先查看下面的参考资料。

Linux Ubuntu 安装:

cd到您希望安装文件所在的位置,然后执行以下操作:

# 1. Obtain the Uber fork of the arcanist program by cloning it into an "uber" directory.
mkdir uber
git clone https://github.com/uber/arcanist.git uber
# 2. Symbolically link the `arc` program to your ~/bin directory so you can call `arc` from anywhere.
# - this assumes that ~/bin is in your PATH.
# Ensure the ~/bin dir exists; if just creating this dir for the first time you may need to log out of Ubuntu
# and log back in AFTER running the `mkdir` command below, in order to force your ~/.profile script to 
# automatically add ~/bin to your PATH (assuming your ~/.profile script does this, as default Ubuntu scripts do).
mkdir -p ~/bin
ln -s $PWD/uber/arcanist/bin/arc ~/bin

现在尝试运行arc。它应该失败并显示以下消息:

$ arc
ERROR: Unable to load libphutil. Put libphutil/ next to arcanist/, or update your PHP 'include_path' to include the parent directory of libphutil/, or symlink libphutil/ into arcanist/externals/includes/.

因此,请执行以下操作:

# 3. Obtain the libphutil program.
# - Note that git cloning it like this `git clone https://github.com/phacility/libphutil.git` will NOT work anymore
# for Uber's fork of arcanist because the libphutil project is now empty. So, do this instead:
sudo apt install libphutil
# 4. symbolically link the libphutil program into arcanist.
# First, we need to know where it is installed.
dpkg -L libphutil
# Now look at the output from the above command. Mine shows libphutil is installed in "/usr/share/libphutil/",
# so do the following:
ln -s /usr/share/libphutil uber/arcanist/externals/includes

现在测试arc命令,您应该看到以下内容:

$ arc
Usage Exception: No command provided. Try `arc help`.

运行arc help以查看帮助菜单或arc help --full完整的帮助菜单。

让我们 grepflowcascade证明它们仅在 Uber fork 的帮助菜单中(但不是主要奥术师):

在完整flow的帮助菜单中寻找:

$ arc help --full | grep flow
          This workflow is primarily useful for writing scripts which integrate
              soft version of '' used by other workflows.
      flow [options]
      flow name [options]
      flow name upstream [options]
          step in the standard Differential pre-publish code review workflow.
          The workflow selects a target branch to land onto and a remote where
          Consulting mystical sources of power, the workflow makes a guess
          step in the standard Differential pre-publish code review workflow.
          The workflow selects a target branch to land onto and a remote where
          Consulting mystical sources of power, the workflow makes a guess
          code review workflow.
          The workflow selects a target branch to land onto and a remote where

cascade完整的帮助菜单中:

$ arc help --full | grep -A 4 cascade
      cascade [--halt-on-conflict] [rootbranch]

          Automates the process of rebasing and patching local working branches
          and their associated differential diffs. Cascades from current branch
          if branch is not specified.
--
              Rather than aborting any rebase attempts, cascade will drop the
              user
              into the conflicted branch in a rebase state.

参考:

  1. Phacility 的奥术师(缺少arc flowarc cascade功能):https ://github.com/phacility/arcanist
  2. Uber 的 Arcanist 分支(已添加arc flowarc cascade功能):https ://github.com/uber/arcanist
  3. Arcanist 用户指南:https ://secure.phabricator.com/book/phabricator/article/arcanist/ --> 有关如何在 Windows、Mac、Linux 或 FreeBSD 中安装 Arcanist 的说明,请参阅“安装 Arcanist”部分。
  4. 错误:无法加载 libphutil

有关的:

  1. git 分支在树中的输出,如时尚
于 2019-01-17T07:57:09.133 回答
0

这可能与git 嫁接有关,您在其中进行提交/修订,并更改其父提交,从而更改存储库的历史记录。
(虽然,自 Git 2.18,2018 年第二季度以来,graft 已被 git 取代ref/replace/

与补丁相反,补丁只是从现有差异创建新的提交/修订,添加到回购的历史。

于 2019-01-17T06:03:02.007 回答