Checkout bitbucket pull requests locally - bitbucket

I found this gist, showing how to check out a pull request locally from GitHub.
I'm using bitbucket and I'm looking for a similar function.
Can you help me?
Thank you

One may fetch the code from Bitbucket Server's pull requests using:
git fetch origin refs/pull-requests/$PR_NO/from:$LOCAL_BRANCH

I found this answer and thought that it was actually possible to fetch refs for a pull request on bitbucket.
But it's not.
The answer for the OP's question is that it is NOT possible: there's been an open feature request issue about it that has been unanswered and unattended for four five SIX SEVEN years.
The workaround?
You can get the PR as a downloadable .patch file you can download and apply to a new branch you create manually. But you won't easily be able to apply updates.
I figured another way out, which I've implemented in git-repo, so everybody can use it. What I'm doing is use the API to get the PR's remote and branch, and automatically create a new upstream and branch locally. That way you can get updates from the PR poster. The downside is the clutter of git remotes.
edit: I hope this gets done and the feature request is closed. But there has been a solution for this on dedicated bitbucket servers for some time now, but not on the bitbucket.org service. On June 5th, a bitbucket staff member commented on this ticket:
Hi y'all -- thanks again for your feedback and patience on this issue. This feature is still high on the priority list in the backlog. When we have more information to share about the expected delivery of this feature, we will share it here.

I followed this article Pull request Fetching.
It worked but I found out I just need add one line to the current repo, rather than create a folk repo and an upstream repo. Run this line
git config --add remote.origin.fetch '+refs/pull-requests/*/from:refs/remotes/origin/pr/*'
You can also add it manually to the file .git/config in your project.
Next run git pull you should see a list:
[new ref] refs/pull-requests/488/from -> origin/pr/488
[new ref] refs/pull-requests/666/from -> origin/pr/666
Then you can run git checkout origin/pr/666 to get the pull request changes.

Fetch/Checkout Pull Requests
This works for bitbucket. Other server could have different refs: (refspecs) or no refs: at all.
First Time
First of all you need to add the pull request refs: of the remote repository. To do that to a repository (e.g. aliased 'upstream'):
git config --add remote.upstream.fetch '+refs/pull-requests/*/from:refs/remotes/upstream/pull-requests/*'
That is, you add the last line on git .config file:
[remote "origin"]
url = ssh://git#git.blablabla.net/~user/repository.git
fetch = +refs/heads/*:refs/remotes/origin/*
fetch = +refs/pull/*/head:refs/remotes/origin/pull-requests/*
Fetching
Then if you perform the remote fetch you should see the retrieval of (also) all the pull requests:
git fetch upstream
From ssh://git.blablabla.net/somepath/repository
* [new ref] refs/pull-requests/1188/from -> upstream/pull-requests/1188
* [new ref] refs/pull-requests/1741/from -> upstream/pull-requests/1741
* [new ref] refs/pull-requests/2394/from -> upstream/pull-requests/2394
Checking out
Finally you can checkout the pull-request you prefer:
git checkout pull-requests/2723
Successfully tested on dedicated bitbucket server 27/02/19.

When is not possible to checkout the pull request, a trick is that you can checkout the last commit of that pull request
git checkout <hash code of last commit>

If you use forks probably "origin" is your fork, so first of all you should add the main remote.
Take the URL of the main remote clicking the "Clone" button in the repository page the same way you do when you clone a repository
git remote add upstream $UPSTREAM_URL
fetch the pull request
git fetch upstream refs/pull-requests/$PR_NO/from:$LOCAL_BRANCH
checkout the new branch
git checkout $LOCAL_BRANCH

If you are using forked repository and you want to pull PR from original or other repo then use below commands.
1. git fetch ${URLofOriginalRepo}
“+refs/pull-requests/*/from:refs/remotes/origin/pr/*”
2. git checkout origin/pr/${PR_NUMBER}
URLOfOriginalRepo is the url repository from which you want to pull the PR. This url is the one you use to clone the repo using ssh key.
After running these command you can see the open PR's on this repo. Then pull the one you want.
for eg.
git fetch ssh://hostname.net:8080/repofolder/repo.git.git “+refs/pull-requests//from:refs/remotes/origin/pr/”
&&
git fetch origin/pr/854

It seems the easiest way to do this is still to get a patch of the pull request. Based on this question's answer, Alexandre's comment is still the only way to do this. It uses this BitBucket API call.
I used the following bash script:
USER=username
PASSWORD=password
REPO=repo-name
PULL_NO=42
OUTPUT_FILE=output.patch
# Add -i to include the HTTP-header in the output for debugging
curl -u $USER:$PASSWORD https://bitbucket.org/api/2.0/repositories/$USER/$REPO/pullrequests/$PULL_NO/patch -L -o $OUTPUT_FILE
Save that to a file called pull-patch.sh and fill in the environment variables with your account details. The script requires that you have curl installed (e.g. sudo apt install curl). Then run:
chmod +x pull-patch.sh
./pull-patch.sh
And a file called output.patch should be created from the pull request.

In bitbucket what you can do is
git config remote.origin.fetch "+refs/heads/:refs/remotes/origin/"
and then
git fetch
after that you can checkout to the branch you want to
git checkout BRANCH_NAME
P.S: Hopefully bitbucket will sort this out https://jira.atlassian.com/browse/BCLOUD-5814

I found this difficult in bit bucket, so, I tried a different approach. If a person give a pull request to my repo in bitbucket, i set his(bill) origin by him name(bill) . then to this -
git checkout -b bill-auth bill/bill-auth
Here bill is that contributer repo origin / link , then bill-auth is his branch name.
Here I am creating a branch same name as his(bill) feature branch.

git fetch origin refs/pull-requests/$PR_NO/merge - it works for Butbucket v5.14.1

Related

Correct way of committing changes to master branch on Github

So I am very new to Github. Please forgive me if i am asking a stupid question. So first did some reading on Github and tried to understand the philosophy about it. So i am working on my first ruby on rails app (very excited) I generated my new app and made my first commit by pushing the empty app to Github. So now i have a master branch.
Then i created a couple of models and added some fields to the tables i made. Now i would like to push this change on Github . What do i do and how? I KNOW some of you will say why would you push a change so small but i am just trying to learn GIT so then when i work on huge projects i am ready.
I basically want to commit the changes to the masters . How do i do this? I USUALLY see other peoples gits and they have messages like "fixed feature 1" 1 hour ago etc. So i want to do the same.
Please advice.
You would do that just like you pushed your earlier code - by pushing the commits you have made to remote repository.
If you are on the master branch, this will do: git push origin master (replace origin with your remote name - git remote -v will tell you all your remote names).
If you are on a feature branch, you can checkout to the master branch and then merge your feature branch - git checkout master and then git merge <feature branch>, and then push your changes again using git push origin master.
EDIT:
You can add a shortname using git remote add origin <link to remote repository>, and then use origin to push.
I am new to git as well and the answer above sounds better then mine. I have bash script on github (https://github.com/caroldomokos/columbo) which is work in progress for some time. I have the master locally as you do. When I make a change on the script I first do "git commit -a" and then "git push". I am in the "columbo" forlder on my pc. If you add a new file you first have to tell git to add it: "git add ". You can always use "git status" to see what is tracked and what has changed.To examplify I created this small sequence for you :-)
hpbcadom#LUBUNTU32:~/columbo$ echo "Git example" > example_file
hpbcadom#LUBUNTU32:~/columbo$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
(use "git add ..." to include in what will be committed)
example_file
nothing added to commit but untracked files present (use "git add" to track)
hpbcadom#LUBUNTU32:~/columbo$ git commit -a
[master d799b3a] to help I hope
1 file changed, 1 insertion(+)
create mode 100644 example_file
hpbcadom#LUBUNTU32:~/columbo$ git push
warning: push.default is unset; its implicit value is changing in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the current behavior after the default changes, use:
git config --global push.default matching
To squelch this message and adopt the new behavior now, use:
git config --global push.default simple
When push.default is set to 'matching', git will push local branches
to the remote branches that already exist with the same name.
In Git 2.0, Git will default to the more conservative 'simple'
behavior, which only pushes the current branch to the corresponding
remote branch that 'git pull' uses to update the current branch.
See 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)
Username for 'xxxs://github.com': caroldomokos
Password for 'xxxs://caroldomokos#github.com':
Counting objects: 4, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 288 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
To xxxs://github.com/caroldomokos/columbo
dadf5af..d799b3a master -> master
I hope it helps :-)

Git Working tree is dirty

If I execute git review git shows me "Working tree is dirty" error.
I made a commit and I sent to review. After that I update the branch from the upstream using git pull. Now I need to modify the previous commit message, so, there are my commands:
1) git reset <id-of-the-commit-to-modify>
2) git commit --amend
vim was opened to modify my commit. But here appears information about my commit and others commits as well and I don't know why. However, I modified the commit message and write/close vim.
3) git review
This command raise this error:
Errors running git rebase -i remotes/gerrit/master
doc/source/configuration.rst: needs update
doc/source/developing.rst: needs update
tools/sample_data.sh: needs update
Working tree is dirty
What I doing wrong?
git reset <id-of-the-commit-to-modify> without a mode option is defaulted to --mixed . This is what is said on the reset in the manual
--mixed
Resets the index but not the working tree (i.e., the changed files are preserved but not marked for commit) and reports what has not been updated. This is the default action.
This basically means your index has been reset, but not your working files. So all files that you pulled from upstream are still left in your working tree.
You should use git reset --hard <id-of-the-commit-to-modify> This will reset your index and remove the files that came with your upstream pull. You can then amend your commit and send it for review.
once a change was pushed to Gerrit, then it can be fetched directly. On the Gerrit review board you can find the chekcout command for each patchset, something like this: git fetch ssh://ebalbar#gerrit.ericsson.se:29418/TCC/TitanSim refs/changes/86/129686/5 && git checkout FETCH_HEAD Then, you can amend the commit as usual, and push the new change again. AFter that checkout your local branch and reset it with the remote branch: git reset --hard origin/<remote_branch> also a nice answer how to modify a commit which was pushed directly.

Keep track of which git branch is currently deployed to a Heroku server

I know there is a http deploy hook I can use but unfortunately it does not submit the branch name, here is what it does submit:
{"head"=>"7021419", "app"=>"appname", "git_log"=>"commit message", "action"=>"home", "url"=>"site url", "prev_head"=>"1d844b0", "controller"=>"account_sessions", "user"=>"heroku#user.com", "head_long"=>"7031429230228988d8f3312fa9e74d77b6c1bc14"}
I tried using the head or head_long to figure out the branch name with:
git branch --contains SHA
Which worked, but it is not 100% accurate as the same SHA could be in multiple branches. Same can be said about:
git reflog show --all | grep 7021419
I am pretty sure it is impossible to get the current branch name from within the deployed app as the branch deployed to Heroku is always the "master" branch. I was hoping I can send the deploy callback hook to another server and store the deployment record somewhere.
1. Detecting only
If it's just about heads, use
git rev-list --no-walk --glob=refs/heads
with a bit of --format and grep logic tacked on
2. Tracking locally
The simplest way would be using a tag.
Push the tag like a normal branch:
git push herokuremote tagname:publicbranchname
Unfortunately, that would just push the tag, not a branch... ; read on for alternative
(note I don't know/use heroku, so I don't know the naming conventions, sorry)
3. Symbolic branch reference
If you don't mind using a bit of plumbing, you can name a local ref as the one deployed. You can have a symbolic ref for the purpose:
git update-ref -m "deployed release candidate" --no-deref refs/heads/deployed master
If the same SHA is in multiple branches, they are effectively the same branch (at least at that point in time). If you're sure that SHA is the last commit of a branch, you can find it in .git/refs/heads/* where * is a list of files whose names correspond to branch names and contents are the SHAs.
It seems like you might be able to solve this recording problem by not using their API. Wrapping your deploy script (or Heroku's deploy binary, or a post-push hook) should give you the flexibility you need to notify a different service for record keeping.

Gerrit hook API

I'm using Gerrit Code review.
I have a problem with it. There are some hooks with Gerrit, one of them is:
patchset-created --change <change id> --change-url <change url>
--project <project name> --branch <branch> --uploader <uploader>
--commit <sha1> --patchset <patchset id>
Gerrit will call it if you push some change to Gerrit.
The commit parameter passed in is the sha1 commit number, but what I want is the commit log. For example, if I do git commit -m "id:110", I want to get id:110.
How can I get it? Is there any API I can use?
You can use git log or git show, run from within the correct repository. Your hook will be passed the repo via --repository. The hook will be called from a useful working directory (I just checked into this last week, I think it cd's into the repo before running the hook?)
git log $SHA1 or git show $SHA1 depending on which information you want.
That said, I'd prefer a better solution. I'm looking to add the diff / patchset to the information, and it is not available via any of the gerrit hooks.
i have solve the problem myself.it seems that gerrit has not such apis.
but , if patchset-created hook is called , the change parameter it passed in is usefull,
if refer to a private key of gerrit database table ,named Change ,every git push to gerrit it record such change to the Change table , include the commit message , so , you can use the change parameter to query the table , so got the commit message from the hook !

How to switch repositories from one to the next

I was using a github repository from a previous developer.
I am the only coder on this project, so I forked the project over to my own github repository.
Now I would like to commit soley to my repo.
Unfortunately, I realized that I never changed my .git/config , so I was still committing to the old repo. I just changed it to the appropriate url, and when I type :
$> git status
It returns :
=> Working directory clean.
But I know its not because I have several commits I've made. So my local box has different code then what it is pointed to on my repository.
My question is this. Obviously I'm halfway through the process of doing this. Do I need to re-fork to update, and then I'm good. Or is there a special command I need to run to let my local box know its 'git status' command is targeting a new repo to compare itself to? Equally, am I missing something else very important :D ?
Thank you everyone.
You can use git remote to manage your remote
rename origin
git remote rename origin old_origin
add a new origin
git remote add origin git://github.com/my/forked/repo.git
git fetch origin # will create all the remote branches references
# in your local repo
You can also easily setup a new upstream for your current master branch (git 1.7 and more):
git branch --set-upstream master origin/master
The "nothing to commit (working directory clean)" message of git status won't prevent you to push.
After changing the origin, you should see:
$ git status
# On branch master
# Your branch is ahead of 'origin/master' by xxx commits.
#
nothing to commit (working directory clean)
That means you have some commits to push to your new origin.
Note: "git remote"(man) rename failed to rename a remote without fetch refspec, which has been corrected with Git 2.39 (Q4 2022).
See commit 5a97b38 (22 Sep 2022) by Jeff King (peff).
(Merged by Junio C Hamano -- gitster -- in commit 20a5dd6, 10 Oct 2022)
remote: handle rename of remote without fetch refspec
Reported-by: John A. Leuenhagen
Signed-off-by: Jeff King
We return an error when trying to rename a remote that has no fetch refspec:
$ git config --unset-all remote.origin.fetch
$ git remote rename origin foo
fatal: could not unset 'remote.foo.fetch'
To make things even more confusing, we actually do complete the config modification, via git_config_rename_section().
After that we try to rewrite the fetch refspec (to say refs/remotes/foo instead of origin).
But our call to git_config_set_multivar() to remove the existing entries fails, since there aren't any, and it calls die().
We could fix this by using the "gently" form of the config call, and checking the error code.
But there is an even simpler fix: if we know that there are no refspecs to rewrite, then we can skip that part entirely.
git status only shows you the status of your working directory, not the entire repository. It seems like you only need to change the remotes that git push and git pull use by default. Open up .git/config and find your branch.<branch> entries and change them, as well as your remote.<remote> entries. For example, your master entry may look like this:
[branch "master"]
remote = origin
merge = refs/heads/master
Just change remote to reference your (forked) remote.
Also, your remote entry may look like the following:
[remote "myremote"]
url = git://github.com/me/repo.git
fetch = +refs/heads/*:refs/remotes/origin/*
You can add a push entry so that your master branch is pushed by default:
[remote "myremote"]
url = git://github.com/me/repo.git
fetch = +refs/heads/*:refs/remotes/origin/*
push = master
In whole, but I should include it in this answer. Is that before hand I manually altered my .git/config to include my new repository url. That's why I didn't have to rename or add any origin as Von suggested.
Then I just guessed this and performed
$> git fetch origin
Which returned
From git#github.com:gotoAndBliss/hq_channel
17326ca..043d395 master -> origin/master
* [new branch] panda_streaming -> origin/panda_streaming
+ 6ec9bf8...becbcc6 testing -> origin/testing (forced update)
Then on git status I got
# On branch testing
# Your branch is ahead of 'origin/testing' by 9 commits.
I git pushed origin testing, and I think I'm on target now.

Resources