Phabricator - arc land throws an Exception due to a wrong git call - bug-tracking

I am playing around with phabricator and recently ran into an issue with arc land:
I created a test-repository, did a commit and got it into phabricator with arc diff. Worked as expected. The commit lives under a branch called "new_feature".
In phabricator the diff was rejected for testing purposes. After rejecting, I tried arc land:
$ ~/git/test> git branch
master
* new_feature
$ ~/git/test> arc land
Landing current branch 'new_feature'.
Switched to branch master. Updating branch...
Exception
Command 'git pull --ff-only' failed with error #1:
stdout:
stderr:
You asked me to pull without telling me which branch you
want to merge with, and 'branch.master.merge' in
your configuration file does not tell me, either. Please
specify which branch you want to use on the command line and
try again (e.g. 'git pull <repository> <refspec>').
See git-pull(1) for details.
If you often merge with the same branch, you may want to
use something like the following in your configuration file:
[branch "master"]
remote = <nickname>
merge = <remote-ref>
[remote "<nickname>"]
url = <url>
fetch = <refspec>
See git-config(1) for details.
Next step the reviewer accepted the patch but arc land threw the same Exception.
Ideas?

Related

Push gitlab repository code to Google source repository

I followed below article to push gitlab repository code to Google cloud source repository but I'm getting an error on this command
git push -f google master
error: src refspec master does not match any.
error: failed to push some refs to 'https://source.developers.google.com/p/project/r/test/'
Article followed:
https://medium.com/#bamnet/cloud-source-repositories-gitlab-2fdcf1a8e50c
Is there anything , I'm doing wrong 😜? Any thoughts as to how I can avoid this error message?
src refspec master does not match any
The issue is the date of the article you are following: Aug. 2018.
GitLab Runner has changed since then, more precisely in May 2019.
The problem is described in this thread from May 2019:
Since we are using refspec to clone/fetch the repository, we checkout a specific commit and not checking out a specific branch.
When the script does git push master, the branch is nowhere to be found so git doesn’t know what to push.
That was because of, on GitLab side, MR 1203:
Basically, GitLab CE/EE sends refspecs parameter to GitLab Runner gitlab-org/gitlab-foss app/presenters/ci/build_runner_presenter.rb: this parameter is to used in GitLab Runners for fetching branch/tag refs from remote repository.
This change was introduced because we wanted GitLab Rails side to leverage respecs in order for issue 7380 "Combined ref pipelines (source+target branch)" though, there should not be a big difference between git clone $URL or mkdir $REPO_DIR && git remote add origin $URL && git fetch +refs/heads/branch_name:refs/remotes/origin/branch_name.
In fact, the new behavior has already run on our development project
https://gitlab.com/gitlab-org/gitlab-ce/pipelines and has no issues so far.
Issue 4097 was opened at the time
Workaround
Use HEAD when you want to push this to another remote.
deploy:
stage: deploy
script:
- git remote add heroku https://heroku:$HEROKU_API_KEY#git.heroku.com/<project>.git
- git push -f heroku HEAD:master
So don't push master. Push HEAD.
The OP Adam uses another workaround and add:
before_script:
- git checkout master

can't push to gitlab, failed and rejected

has been pulled, the result is still an error ! [rejected] dev->dev(non-fast-forward)
D:\PPI_Roketin\Project\astrowatch (dev)
λ git add resources/views/reals/_form.blade.php
D:\PPI_Roketin\Project\astrowatch (dev)
λ git commit -m "resources/views/reals/_form.blade.php"
[dev db5ac99] resources/views/reals/_form.blade.php
1 file changed, 2 insertions(+), 2 deletions(-)
D:\PPI_Roketin\Project\astrowatch (dev)
λ git push origin dev
To gitlab.com:roketin-stellar/astrowatch.git
! [rejected] dev -> dev (non-fast-forward)
error: failed to push some refs to 'git#gitlab.com:roketin- stellar/astrowatch.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
error like this, why?
have done git checkout, and repeated the command, it's still an error like above
This is a classic git error. The problem is described in the error message: Updates were rejected because the tip of your current branch is behind, which means that there have been changes to the remote branch that you do not have locally. There are quite a few ways to fix this, one of which is also described in the git message: Integrate the remote changes (e.g. hint: 'git pull ...') before pushing again.
If you do git pull origin dev this will merge whatever changes are made in the remote to your local branch. Once you fix the merge conflicts, you can then push the branch.
Another option would be to run a rebase by performing git pull --rebase origin dev, which will bring in the remote changes and rebase your commits on top of the remote commits. This will result in a cleaner git history.
The easiest for now would probably just doing a git pull, then once it's merged correctly, pushing to your remote.
I definitely recommend researching the git commands and learning how to find the resources correctly in the docs. There is a lot available online.
you can try git reset --hard HEAD
please remind that:
HEAD points to your current branch (or current commit), so all that git reset --hard HEAD will do is to throw away any uncommitted changes you have.
It's quite self explanatory, you need to keep yourself upto date with remote branch if you want to commit and it looks like git pull will overwrite files you've made changes to. You should commit your changes first.

why did I have to run this git command?

After checking out the branch of a colleague, at some point
I couldn't push or pull from remote.
Each time I ran git push or git push origin branch_name or those variant, I always got a everything up to date even though I had committed changes. Ultimately, what did the trick was git push -f origin HEAD:origin/branch_name. So my question is, why did I have to run this? what did I do to get there?
the fatal error I got was:
fatal: You are not currently on a branch.To push history leading to current (detached HEAD) state now, use: git push origin HEAD:<name-of-remote-branch>
Current State: Your head isn't attached to a branch, so you pushed with the branch whose history was the same as the remotes. You were working with a detached head, so when you pushed the head instead of the branch, it worked.
If you do a git status it with show:
HEAD detached at XXXXXXX
Fixing it:
Now that your remote has the changes you made, you can checkout the branch_name and pull your changes from remote. Your branch_name should already be tracking that remote branch.
Why you had to do this: You somehow detached your head. Without knowing the commands you used, we won't be able to tell you why you had to do this.
An example of how you could have done this:
#Don't do this, because force pulling will make you lose your work.
git checkout --detach
git pull --all -f #Don't do this.
You should probably edit (parts of) your last two ... er, now, three—comments into your question, but for now, I'll just quote them here:
I found where I might have off road. When I checked-out the branch I was going to work on, I got this message (let's called the branch b1:
Branch b1 set up to track remote branch b1 from origin.
Switched to a new branch 'b1'.
I checked-out the branch this way:
git checkout b1.
Then when I tried to push I did:
git push --set-upstream origin b1.
Branch b1 set up to track remote branch b1 from origin.
Everything up to date
OK, in that case you are probably fine.
git checkout
The problem you are running into here (well, in my opinion it's a problem) is that git checkout crams three or four (or more, depending on how you count) different things into one command.
Normally you would use:
git checkout somebranch
to check out (switch to) your local branch somebranch. Of course, that's great for branches you already have, but no good for branches you don't have locally yet. So Git crams another, different, command into git checkout: the "create new branch, then switch to it" command.
Normally this command is spelled git checkout -b newbranch. The -b flag means "create new". It's pretty reasonable to have this command spelled the same as git checkout, with just a flag, since we're switching to this newly created branch, but it probably would be clearer if it were a separate command, such as git create-and-then-switch-to-new-branch.
Now, pretty often, when you are creating a new local branch, you are doing so with the intent of having it "track" (as its "upstream") some existing remote-tracking branch, origin/b1 or whatever. In this case, you originally had to type in:
git checkout -b b1 --track origin/b1
which is still really obvious: create new branch b1, base it off remote-tracking branch origin/b1, and make it track (have as its upstream) origin/b1. Again, this might be clearer as git create-and-then-switch-to, but it's not so bad to have it shoved into git checkout, plus checkout is a lot shorter to type!
Now, many years ago (back in 2013 or so), the Git folks saw that this action was pretty common, and decided to make Git do it "magically" for you under certain conditions. If you write:
git checkout b1
and you don't currently have a branch b1 and you do currently have an origin/b1 and you don't have any other remote-tracking branch whose name ends in b1, then (and only then!), git checkout uses the create-and-then-switch-to-new-branch command, with the --track flag. So:
git checkout b1
means
git checkout -b b1 --track origin/b1
in this one special (but common) case.
--track means "set upstream"
Each branch (well, each named, local, branch) can have one (1) "upstream" set. The upstream of a branch has a bunch of uses: git status, git fetch, git merge, git rebase, and git push all look at the upstream. Having an upstream set makes git status show how many commits you are ahead and/or behind of the current branch's upstream. And, it lets you run all the other commands with no additional arguments: they can figure out where to fetch from, or what to merge or rebase, or what to push, using the current branch's name and its upstream setting.
Branches do not have to have an upstream, and a new branch you create doesn't, by default. Moreover, if it's a "very new" branch—one that does not exist on origin, for instance—there's no origin/name yet to have as an upstream in the first place. But when you create a new branch from a remote-tracking branch, setting the remote-tracking branch as the upstream of the new branch is almost always the right thing.
(Note: having an upstream also affects git pull because git pull is just git fetch followed by either git merge or git rebase. Until they are very familiar with Git, I think most people are noticeably better off running git fetch first, then git rebase or git merge second, depending on which one they want—and more often, that's actually git rebase, which is not the default for git pull: git pull defaults to using git merge second. Once they are familiar with the fetch-and-whatever sequence, then people can configure git pull to do the one they intend, and use git pull as a shortcut to run both commands. However, there are times to keep them separate anyway.)
For completeness
The other things that git checkout can do, that don't change the current branch, are:
copy files from the index to the work-tree: git checkout -- <paths>, including the special git checkout --ours and git checkout --theirs variations
copy files from specified commits to the index and then on to the work-tree: git checkout <tree-ish> -- <paths>
restore conflicted merge files to their conflicted state: git checkout -m -- <paths> (as with --ours and --theirs, this only works during a conflicted merge)
interactively patch files: git checkout -p (this variant gets especially complicated and I'm not going to address it further)
The checkout command can also "detach HEAD" (see previous answer below) and create "orphan" branches, but both of these effectively change your current branch, so they don't fall into this special "non-branch-changing" class of checkout operations.
So what happened with the first git push
When you ran:
git push --set-upstream origin b1
you told your Git to contact the other Git on origin, give it the commit ID to which your branch b1 pointed, see if it needed any of those commits and files (it didn't), and then ask it to set its branch name b1 to point to the same commit.
Now, you'd just created your own local b1 from your origin/b1, which you recently git fetch-ed from origin, so your b1 already pointed to the same commit (you did not make any new commits) and hence your git push gave them their own commit hash back and they said "Well, gosh, that's what I already have! We're all up-to-date!" And then their Git and your Git said goodbye to each other, and your Git carried out your last instruction: --set-upstream.
This changed the upstream of your local branch b1 to origin/b1. Of course, this was already the upstream for your local branch b1, so that was not a big change. :-) But your Git did it anyway, and then reported that everything was still up to date.
Earlier answer (was mostly done when you added your third comment)
... I had one file committed with changes. git status didn't return nothing after I committed.
git status should always print something, such as (two actual examples):
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
or:
HEAD detached at 08bb350
nothing to commit, working directory clean
In this second case, you are in "detached HEAD" mode. This special mode means you are not on a branch—or it may be more accurate to say that you are on the (single, special-case) anonymous branch that goes away as soon as you get on any other branch.
Any commits you make while in detached HEAD mode are perfectly fine, normal commits—except that there is no branch name that will make them permanent. This means these commits can go away once you switch to some other branch.
All my attempts to push were unsuccessful.
Again, actual git push output might help here, so one could tell why the push failed or did nothing. If it complained about being in "detached HEAD" mode, that would be significant: we would know that you were in the detached HEAD mode.
git fetch -a didn't return nothing as well.
(Just an aside: It's a bit odd to use -a here: that flag is almost never useful to humans and is intended more for scripting purposes. It just makes your fetch append to FETCH_HEAD rather than overwriting it. The special FETCH_HEAD name is meant for scripts to use.)
the last step I had were to git checkout origin/branch_name.
This will take you off whatever branch you were on before, and put you in "detached HEAD" mode. If you used to be in "detached HEAD" mode, it will abandon your previous anonymous branch and put you on a new, different anonymous branch.
Any commits you made while on the previous anonymous branch are ... well, not lost, precisely, but are now difficult to find (and set to expire after 30 days).
When I tried to push from there I got the following message:
fatal: You are not currently on a branch.
To push history leading to current (detached HEAD) state now, use:
git push origin HEAD:<name-of-remote-branch>.
Which I did [... HEAD:origin/branch_name] and it worked
Yes, but alas, this did nothing useful, because you are now on an anonymous branch that is exactly the same as origin/branch_name. This ends up asking the remote to create—on the remote, as a local branch there—the name origin/branch_name. That's probably not a good idea, since having a local branch named origin/branch_name is like having a bicycle named "motorcycle". If you also have a motorcycle and ask your friend to bring you "motorcycle", which will he bring you, the bicycle named "motorcycle", or the motorcycle?

`ssh -vT git#github.com` works fine, and agent is in github ssh keys. Where is the issue?

I just bought a new machine, and I'm working on a new github repo. I clone it into my machine using
git clone git#github.com:<username>/<exact-repo-name>.git
and it clones fine:
Cloning into '<exact-repo-name>'...
remote: Counting objects: ###, done.
remote: Total ### (delta 0), reused 0 (delta 0), pack-reused ###
Receiving objects: 100% (###/###), ### KiB | 0 bytes/s, done.
Resolving deltas: 100% (###/###), done.
Checking connectivity... done.
And, I add all of the remote branches locally by doing:
for remote in git branch -r; do git checkout -b $remote; done
Then, when I try to pull from any of the branches, using
git pull origin/<branch-name>
I get the ever-so-common error:
origin/<branch-name> does not appear to be a git repository
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
So, I go through all of the steps:
ssh -vT git#github.com
ssh-add -l
eval "$(ssh-agent -s)"
These all succeed, and I check the output of ssh-add -l and I see that it is in the list ssh keys on my github account. I go into Settings -> ssh keys, and I see the agent there.
Are there certain user permissions that are on top of those for ssh?
I agree with #Felix that this most likely is not an SSH problem, though it might be masquerading as this. Instead, I think you have a problem with your path. You can try running git clone like this:
git clone https://username#github.com/username/exact-repo-name.git
Here the username is your GitHub username. Git will prompt you for a password so you don't have to enter it as plain text. Please read this SO article for more information.
It's probably not an ssh issue, as an ssh problem would normally result in a message like
fatal: The remote end hung up unexpectedly
Most likely it's a path problem: either you have an extra slash or space in the remote path (or if there's supposed to be a space, you're missing quotation marks in your command line), or some letter is the wrong case. Double-check the rest of the URL. It could also be exactly what it says, a permissions problem -- are you sure you're connecting as the right user for this repository?
Edit: from your added details, it looks like you're just getting the syntax of the pull command mixed up. Does it work if you do this?:
git checkout <branch-name>
git pull # Edit: don't do this without reading all of 'git help pull'
? Also, does git fetch --all work? (git pull is just git fetch followed by git merge.)
Further edit: I can reproduce your error; it is a command syntax problem. Here are more examples:
"source" is a git repository in a local folder; I clone it into a folder called "dest":
$ git clone source dest
$ cd dest
Now I do the git branch command in your for loop:
$ git branch -r
origin/HEAD -> origin/master
origin/branch1
origin/branch2
origin/master
I would expect that first line to cause problems, since that would result in these commands being run in your for loop:
git checkout -b "origin/HEAD"
git checkout -b "->"
...
(Note that your example is missing backticks around `git branch -r`, so if what you posted is literally what you're running, you'll end up with branches called "git", "branch", and "-r", which would really not be what you want... if you had trouble putting backticks into inline code blocks, see https://meta.stackexchange.com/questions/55437/how-can-the-backtick-character-be-included-in-code)
Then if I try your pull command, I get the same error as you:
$ git pull origin/branch1
fatal: 'origin/branch1' does not appear to be a git repository
fatal: The remote end hung up unexpectedly
This is because git pull takes the remote repository name (origin) and the remote branch name (branch1) as two separate parameters, separated by a space. So this works:
$ git pull origin branch1
From /tmp/source
* branch branch1 -> FETCH_HEAD
Already up-to-date.
But, that's probably not quite what you want, because it sounds like you wanted to create a bunch of local branches to track the same named branches on origin (e.g. you want a local branch named "branch1" that tracks "origin/branch1"). Your local branch creation commands didn't include setting up tracking, so what you've actually got is a local branch called "origin/branch1" and a branch on remote repository "origin" also called "branch1", i.e. after running your for loop, the output of git branch -a is:
$ git branch -a
master
origin/HEAD
origin/branch1
* origin/branch2
origin/master
remotes/origin/HEAD -> origin/master
remotes/origin/branch1
remotes/origin/branch2
remotes/origin/master
...So there are two branches called "origin/branch1", and the only thing that differentiates them is that in one case, the repository is your local one and the branch's literal full name is "origin/branch1", and in the other case, the repository is the remote one (named origin) and the branch's literal full name is "branch1", which is notated as "origin/branch1" -- this will probably be very confusing to work with (and in some commands, git will complain and say, "origin/branch1 is ambiguous" and you'll have problems).
Note also that each of the new branches your for loop created is actually just a copy of master (or whatever the default/selected branch was on origin), because you didn't specify a remote branch for them to start from. That is, in your clone command, your local repository was set up with one branch selected (probably master). You then told git "make new branch from where I am now" for each line in your for loop, so each of those new branches, despite having all the different names of the branches on remote, are references to the first branch selected with your clone. This is probably not what you wanted.
I think what you actually wanted was this command, run for each remote branch:
$ git checkout --track origin/branch1
Branch branch1 set up to track remote branch branch1 from origin.
Switched to a new branch 'branch1'
Actually, if you've just done a fresh clone, a git checkout branch1 [without the -b] will have the same effect I think -- since there is no local branch called branch1, git will look for one in the repository you cloned from and set up tracking if it finds one.
...So I guess what this whole post boils down to is:
Leave out the -b in your initial checkout commands
Use a space instead of a slash in your pull command
:)
See https://git-scm.com/book/en/v2/Git-Branching-Remote-Branches and the output of git help pull for more about remote tracking and pulling; some of it is a bit subtle (even more so than all the caveats I mentioned :) ).

Git merge branch of another remote

Nowadays, I see a lot of commits from Linus Torvalds and/or Gitster that look like so:
Merge branch 'maint' of git://github.com/git-l10n/git-po into maint …
* 'maint' of git://github.com/git-l10n/git-po:
l10n: de.po: fix a few minor typos
or:
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upst… …
…ream-linus
Pull MIPS update from Ralf Baechle:
...
* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (22 commits)
MIPS: SNI: Switch RM400 serial to SCCNXP driver
...
I have no idea how would one do that, although, I know about the git remote and git checkout and git merge that I use to merge forks (or "pull requests") but it does not generate such message, why? and how would someone do that (provide examples please)?
P.S: I'm a fan of Linus Torvalds commits etc, like how detailed the description of his merges look ;P
P.S: This is how I used to merge stuff:
git remote add anotherremoot
git checkout -b anotherbranch
git pull remoteshortcut
...do tests...
git checkout master
git merge anotherbranch
git push
The above example I learned from: http://viget.com/extend/i-have-a-pull-request-on-github-now-what
Just use git pull to pull the remote branch into master:
git remote add something git://host.example.com/path/to/repo.git
git checkout master
git pull something master
Or do it without adding a remote:
git pull git://host.example.com/path/to/repo.git
git pull fetches the remote branch, and merges it into the local branch. If possible, it does a fast-forward merge, which just means that it updates the current master to the latest commit without generating a merge commit. But if there are changes on both sides, it will do a merge, like the ones you see Linus and Junio doing, with the remote URL included.
If you want to guarantee that you get a merge commit, even if it could fast forward, do git pull -no-ff. If you want to make sure that pull never creates a merge commit (so fails if there are changes on both sides), do git pull --ff-only.
If you want to include a more detailed message, like the full log that Linus provides, do git pull --log. If you want to edit the message, instead of just using the automatically created message, use git pull --edit. See documentation for git pull for more options.

Resources