Page MenuHomePhabricator

arc diff eagerly detects git-svn repo, which makes arc-patch hang
Open, Needs TriagePublic

Description

After an upgrading, there is error in arc patch (the repo is a git repo converted from SVN repo).

It wrongly detect the git repo as svn repo and hangs there.

lianghu ~/openwrt $ arc patch --trace D2540                                                                                                                                                   
libphutil loaded from '/usr/local/include/php/libphutil/src'.                                                                                                                                 
arcanist loaded from '/usr/local/include/php/arcanist/src'.                                                                                                                                   
Config: Reading user configuration file "/home/lianghu/.arcrc"...                                                                                                                             
Config: Did not find system configuration at "/etc/arcconfig".                                                                                                                                
Working Copy: Reading .arcconfig from "/home/lianghu/openwrt/.arcconfig".                                                                                                                     
Working Copy: Path "/home/lianghu/openwrt" is part of `git` working copy "/home/lianghu/openwrt".                                                                                             
Working Copy: Project root is at "/home/lianghu/openwrt".                                                                                                                                     
Config: Did not find local configuration at "/home/lianghu/openwrt/.git/arc/config".                                                                                                          
Loading phutil library from '/usr/local/include/php/libdisqus/src'...                                                                                                                         
>>> [0] <conduit> differential.querydiffs() <bytes = 75>                                                                                                                                      
>>> [1] <http> http://10.26.130.134/api/differential.querydiffs                                                                                                                               
<<< [1] <http> 155,270 us                                                                                                                                                                     
<<< [0] <conduit> 155,841 us                                                                                                                                                                  
>>> [2] <conduit> conduit.connect() <bytes = 442>                                                                                                                                             
>>> [3] <http> http://10.26.130.134/api/conduit.connect                                                                                                                                       
<<< [3] <http> 207,050 us                                                                                                                                                                     
<<< [2] <conduit> 207,504 us                                                                                                                                                                  
>>> [4] <conduit> differential.querydiffs() <bytes = 198>                                                                                                                                     
>>> [5] <http> http://10.26.130.134/api/differential.querydiffs                                                                                                                               
<<< [5] <http> 245,307 us                                                                                                                                                                     
<<< [4] <conduit> 245,733 us                                                                                                                                                                  
>>> [6] <exec> $ git remote show -n origin                                                                                                                                                    
<<< [6] <exec> 4,141 us                                                                                                                                                                       
>>> [7] <conduit> repository.query() <bytes = 214>                                                                                                                                            
>>> [8] <http> http://10.26.130.134/api/repository.query                                                                                                                                      
<<< [8] <http> 152,494 us                                                                                                                                                                     
<<< [7] <conduit> 152,797 us                                                                                                                                                                  
>>> [9] <exec> $ git diff --no-ext-diff --no-textconv --raw 'HEAD' --                                                                                                                         
>>> [10] <exec> $ git ls-files --others --exclude-standard                                                                                                                                    
<<< [10] <exec> 29,124 us                                                                                                                                                                     
<<< [9] <exec> 33,348 us                                                                                                                                                                      
>>> [11] <exec> $ git diff-files --name-only                                                                                                                                                  
<<< [11] <exec> 18,327 us                                                                                                                                                                     
>>> [12] <exec> $ git svn find-rev 'r46516'

Related Objects

Event Timeline

lianghu raised the priority of this task from to Needs Triage.
lianghu updated the task description. (Show Details)
lianghu added a project: Arcanist.
lianghu added a subscriber: lianghu.

On another workstation, it can proceed like below

$ arc patch D2540
Created and checked out branch arcpatch-D2540.

This diff is against commit
svn://svn.openwrt.org/openwrt/branches/barrier_breaker@46516, but the
commit is nowhere in the working copy. Try to apply it against the
current working copy state? (866c0c9f09a8877dd0a9da3bebc7be764b43d3e8)
[Y/n] Y

So it seems get stuck on the 1st workstation in getting the prompt info.

how does arc detect the base commit? it parsers the commit log? why not .git instead?
we're working with git repo. It's not smart.

avivey updated the task description. (Show Details)Aug 3 2015, 10:13 AM
avivey added a subscriber: avivey.Aug 3 2015, 10:30 AM

It looks like it identifies the repository as a git repo that has an svn remote (git svn find-rev). Is that unexpected?
Did you clone with git clone git://.... or git svn clone svn://....?

When you manually run git svn find-rev 'r46516', does it run correctly?

The base commit (hash / svn revision number) is stored in phabricator as part of the diff information.

If you're working against OpenWrt's git repo directly, and the user that created the diff is using git svn clone, it's possible that the diff was created with svn information, which would confuse arc when patching.

A workaround would be to run arc patch with --no-branch, so it will not try to find it, or maybe adding the svn as another remote (If possible).

I also see that OpenWrt recommend everyone to use the git repo directly - maybe you can convince the rest of the team to re-clone their repositories.

avivey renamed this task from arc patch identify a git repo as svn repo and fails to arc patch identify a git repo as svn repo and hangs.Aug 3 2015, 10:47 AM

I did the clone with git clone git://....
No. git svn find-rev 'r46516' will hangs there without any output.

All our team members are using git repos, no SVN involved but upstream git repo patches has svn info (seems converted from SVN?).

avivey added a comment.Aug 4 2015, 3:27 PM

I was able to reproduce it locally.

When running arc-diff, if we detect a git-svn-id header in the base commit, we choose that over the local git commit (Starting with https://secure.phabricator.com/diffusion/ARC/browse/master/src/workflow/ArcanistDiffWorkflow.php;0d6f3328a08fc2d22f97b9ec43e6b84924ddb62c$2308).

That's desired when actually using git-svn, but in this case (pure git fork of a git-svn project) it's wrong.
It might make sense to use this only in case the local repository really is a git-svn repo (if we can figure it out - I'm not sure how git-svn actually works).

avivey renamed this task from arc patch identify a git repo as svn repo and hangs to arc diff eagerly detects git-svn repo, which makes arc-patch hang.Aug 4 2015, 3:28 PM
lianghu added a comment.EditedAug 6 2015, 3:34 AM

with differential.getdiff

BASE_GIT_COMMIT=$(echo {\"diff_id\": ${DIFF_ID}} | arc call-conduit --trace differential.getdiff | awk -v RS=',' -v FS=':' '$1~/\"sourceControlBaseRevision\"/ {print $2}' | tr -d \")

I get BASE_GIT_COMMIT=svn in the git repo.

I think it's the same thing causing the error.

eadler added a subscriber: eadler.Aug 6 2015, 3:37 AM

Its likely safe to detect the existence of .git/svn/.metadata to determine if it really is a git-svn repo or not.

I think eadler is right.

Someone plan to fix it? It's very annoying bug.

epriestley moved this task from Backlog to arc patch on the Arcanist board.Dec 10 2015, 3:03 PM
award added a subscriber: award.Feb 9 2016, 11:35 PM
eadler added a project: Restricted Project.Sep 15 2016, 6:08 PM

We keep hitting the same thing where a conduit reports an svn commit for "sourceControlBaseRevision" on a repo that is git (was originally svn and was transferred to git).

avivey added a comment.Jan 6 2017, 8:39 AM

@jcarrillo7: Does your local repo has a .git/svn/.metadata file? We're short on actual data for this use-case.
Alternatively, can you fork arcanist for your install?

See also T6072, which might interfere with implementing this.

@avivey my local repo does not have the metadata file but some of the commits do have the git-svn-id in the commit message. I think once we make enough commits on this repo this problem should probably go away but this particular repo doesn't receive commits very often. I would rather not fork arc.

In https://discourse.phabricator-community.org/t/2334, thopre suggests checking for git config --get-regexp svn-remote to see if the repository is configured as git-svn repo, as an alternative to check if .git/svn/.metadata exists.

Krinkle added a subscriber: Krinkle.EditedJul 20 2019, 5:51 PM

See also https://trac.wildfiregames.com/wiki/Phabricator#Downloadapatch where a tedious workaround is needed in order to apply patches to a mirror of an SVN repo that is updated once a day:

If you use a Git-based mirror, arc patch Dnnn may fail because Arcanist demands to find the latest SVN revision in the git-log which might not be mirrored yet. It does this by slowly searching the full git history for a commit message containing git-svn-id: @{latest-revision}, which it will then never find. The --force and --skip-dependencies options do not prevent this issue. To workaround this, use arc patch --patch /file/to.diff instead, like so (the download url can be copied from the "Download Raw Diff" link in the web interface):

curl -L 'https://code.wildfiregames.com/D1991?download=true' > /tmp/arc.patch
arc patch --patch /tmp/arc.patch