“弧形嫁接"和“弧形补丁"之间有什么区别? [英] What's the difference between `arc graft` and `arc patch`?
问题描述
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'.
这对我来说是模糊的.用嫁接"一词来描述嫁接"的含义对我没有多大帮助.
对于那些不了解的人,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
更新2020年3月19日:
请注意, OR
想象一下,您的 但是,一位同事具有以下
简短地说:什么是 使用git创建一个新分支,然后将其上游设置为您想要成为父分支的分支.例如: 现在, 一旁结束. 无论如何,有了上面显示的依赖关系树,您的同事已签出"new_feature_2",并且他们 假设它们的差异为"D999",并且您当前已将"master"分支检出,则命令和生成的依赖关系树将如下所示: 但是,(根据我的问题,我认为)有时候,当他们拥有像这样的多代依赖树时, 但是,一个小问题是,如果您 您的依赖树现在将如下所示: 太好了!尼斯和有条理.现在,您可以签出"new_feature_2"并进行编译和测试.但是请注意,"master"和"graft-D999"将是完全相同的分支,但这没关系. (以防您想在自己的git工作流程中开始使用 注意:Arcanist在Windows上运行(在Windows的 git 中git bash终端),Mac和Linux.我将只介绍Linux安装说明.要获得有关在其他系统中安装的帮助,请先查看下面的参考. Linux Ubuntu安装: 现在尝试运行 因此,请执行以下操作: 现在测试 运行 让 在完整的帮助菜单中查找 和
arc flow
和arc cascade
显然不是 Phacility奥术师的主流版本的一部分.相反,它们只是 Uber奥秘分叉的一部分.在此处.此外,arc cascade
也是Uber的一个分支,它的某些arc cascade
源代码位于 # 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
依赖关系树?回答:这是一个树状结构,通过arc flow
命令显示,该树结构显示了哪些分支取决于什么.作为一个人,您手动进行跟踪是有些武断的事情,因为您知道一个功能依赖于另一个功能.要建立依赖关系",您有两个选择:
arc flow new_branch_name
创建一个新的子分支,或者:
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 rebase(即:将子级重新定位到父级).
arc diff
进行审查.您转到基于Web的差异"工具并开始查看更改.但是,您要对其进行测试.这意味着您需要将它们的差异拉到本地计算机上.您有两个选择:1. arc patch
它们的差异(依赖树感知分支)到本地主机,或者2. arc graft
它们的差异到本地主机.
arc patch D999
.现在,您有了这棵树,其中新创建的"arcpatch-D999"是其"new_feature_2"分支:
master
└──arcpatch-D999
arc graft D999
.您现在拥有了这棵树,就像它们一样:
master
└──new_feature_1
└──new_feature_2
arc patch
将会失败(给出一个错误,指出"Cherry Pick Failed!").在这种情况下,您必须使用arc graft
代替!但是,如果他们的主人与您的主人不完全相同(几乎可以肯定不会,因为他们可能将主人拉了一会儿,而您应该只是拉起主人,以确保您拥有最新的主人),那么您将尝试移植物或补丁将失败.失败可能与以下事实有关:分支历史中的某些提交包含已登陆并存在于您的主数据库中的更改. 解决方案是使用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 graft
的工作量很大,可能会混淆谁创建了哪个分支(您还是其他人?),因此我建议您养成嫁接到新分支上的习惯分支,为组织起自己的名字,如下所示:
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
如何安装Uber的奥术师叉子
arc flow
和arc cascade
):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
以获得完整的帮助菜单.flow
和cascade
的grep证明它们仅在Uber前叉的帮助菜单中(但不用于主要奥术师):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.
参考:
- 设施的奥术师(缺少
arc flow
和arc cascade
功能): https://github.com/phacility /arcanist - Uber的Arcanist分支(已添加
arc flow
和arc cascade
功能): https://github. com/uber/arcanist - Arcanist用户指南: https://secure.phabricator.com/book/phabricator/article/arcanist/->有关如何在Windows,Mac,Linux或FreeBSD中进行安装的说明,请参见安装Arcanist"部分.
- 错误:无法加载libphutil
相关:
arc help --full | less
reveals this for 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.
and this for 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'.
which is vague to me. Using the word "graft" to describe what "graft" means doesn't help me much.
For those who don't know, arc
(Arcanist) is a command-line tool inside of "Phabricator" which acts like a high-level wrapper around Git (or even Mercurial and Subversion) to aid in the development process for large software projects. Here's a few links:
https://phacility.com/phabricator/
Phabricator was originally developed as an internal tool at Facebook.[7][8][9] Phabricator's principal developer is Evan Priestley.[1] Priestley left Facebook to continue Phabricator's development in a new company called Phacility.[2] https://en.wikipedia.org/wiki/Phabricator
Update 19 Mar. 2020:
Note that arc flow
and arc cascade
are apparently not part of the mainstream version of Phacility's arcanist. Rather, they are only part of the Uber fork of arcanist. Some of the arc flow
source code is found here, for instance. Additionally, arc cascade
is also only an Uber fork arcanist feature, and some of its arc cascade
source code is found here.
To learn how to install Uber's fork of arcanist in order to begin using these features in your regular git
workflow (you don't need to use any other features of arcanist if not needed), jump to the bottom of this answer.
ORIGINAL ANSWER Jan. 2019:
So, after some experimenting and trial and error, I think I figured it out:
Both arc graft
and arc patch
use git cherry-pick
under the hood, and accomplish similar things. However, they have some subtle differences, and sometimes arc patch
fails and you must use arc graft
with the --skip-landed
flag instead (update: or perhaps arc patch
with the --skip-dependencies
flag will work too?).
Examples:
# 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
OR
# 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
Imagine your arc flow
dependency tree only contains the "master" branch:
master
A coworker, however, has the following arc flow
dependency tree:
master
└──new_feature_1
└──new_feature_2
Short aside: what's an arc flow
dependency tree? Ans: it is a tree structure, shown via the arc flow
command, which shows which branches depend on what. It is a somewhat arbitrary thing that you as a human are tracking manually, since you know that one feature depends on another. To establish a "dependency", you have two options:
- Call
arc flow new_branch_name
to create a new child branch while you have currently checked-out the branch you want to be the parent, OR: Use git to create a new branch, then set its upstream to what you want to be the parent. Ex:
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
Now, arc flow
will show your dependency tree. This allows you to to things like arc cascade
from a parent down to its children, which is just doing automated recursive git rebases from parents down to children (ie: rebasing children onto parents).
End of aside.
Anyway, with the dependency tree shown above, your coworker has "new_feature_2" checked out, and they arc diff
it for you to review. You go to the web-based "Differential" tool and start reviewing the change. However, you want to test it. This means you need to pull their diff to your local machine. You have two options: 1. arc patch
their diff (dependency-tree-aware branch) onto your local master, or 2. arc graft
their diff onto your local master.
Assuming their diff is "D999", and you currently have your "master" branch checked-out, your commands and resulting dependency trees would look as follows:
arc patch D999
. You now have this tree, where your newly-created "arcpatch-D999" is their "new_feature_2" branch:master └──arcpatch-D999
arc graft D999
. You now have this tree, just like they have:master └──new_feature_1 └──new_feature_2
However, (I think, based on my problems) that sometimes when they have a multi-generation dependency tree like this, arc patch
will fail (giving an error that says "Cherry Pick Failed!"), and in such a case you must use arc graft
instead! HOWEVER, if their master is NOT the exact same as your master (which is almost certainly will NOT be, since they probably pulled their master a while back and you should have just pulled yours to ensure you have the latest), then your attempts to graft or patch will fail. It is likely the failures will be related to the fact that some of the commits in their branch history contain changes which are already landed and present in your master. The solution is to use arc graft D999 --skip-landed
, which will allow you to grab their diff and pull it down, mirroring their arc flow
dependency tree. In such a case, arc patch D999
will likely continue to fail until they pull the latest master and arc cascade
(or git rebase twice), then re-arc diff
to push their changes to the server, at which point you can then arc patch D999
onto your master successfully. Since you can't always get them to rebase/arc cascade
immediately, however, just do the arc graft D999 --skip-landed
now and be done! Let them rebase and re-arc diff
when they get to it.
One minor problem, however, is that if you are arc graft
ing much, it can get confusing who made which branches (you, or someone else?), so I recommend you get into the habit of grafting onto a new branch you name yourself, as follows, just for organization:
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"
Your dependency tree will now be as follows:
master
└──graft-D999
└──new_feature_1
└──new_feature_2
Excellent! Nice and organized. Now you can check out "new_feature_2" and compile and test it. Note, however, that "master" and "graft-D999" will be exactly identical branches, but that's ok.
How to install Uber's fork of arcanist
(in case you'd like to start using arc flow
and arc cascade
in your own git work-flows):
Note: Arcanist runs on Windows (inside the git for Windows git bash terminal), Mac, and Linux. I'll just present the Linux installation instructions. To get help on installing in other systems start by seeing the References below.
Linux Ubuntu installation:
cd
to where you'd like the installation files to live, then do the following:
# 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
Now try to run arc
. It should fail with the following message:
$ 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/.
So, do the following:
# 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
Now test the arc
command and you should see the following:
$ arc
Usage Exception: No command provided. Try `arc help`.
Run arc help
to see the help menu, or arc help --full
for the full help menu.
Let's grep for flow
and cascade
to prove they are in the help menu for the Uber fork only (but not for the main arcanist):
Grepping for flow
in the full help menu:
$ 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
And cascade
in the full help menu:
$ 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.
References:
- Phacility's Arcanist (lacks
arc flow
andarc cascade
features): https://github.com/phacility/arcanist - Uber's fork of Arcanist (has
arc flow
andarc cascade
features added): https://github.com/uber/arcanist - Arcanist User Guide: https://secure.phabricator.com/book/phabricator/article/arcanist/ --> See "Installing Arcanist" section for their instructions on how to install it in Windows, Mac, Linux, or FreeBSD.
- ERROR: Unable to load libphutil
Related:
这篇关于“弧形嫁接"和“弧形补丁"之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!