Open michaeldfallen opened 9 years ago
+1
+1
+1
:+1:
Instead of some new config, use the ref @{upstream}. Then it will use the current branch's upstream (specified by config branch.
@michaeldfallen Do you have any ideas on how we might solve this issue? I'd be happy to raise a PR if you could provide a little bit of guidance.
Not sure I understand git enough to give any guidance. @slackorama's #74 uses git config
to query the reflog and find the branches remote that way. That allows you to know which remote to address in remote/branch
but I'm unsure how to figure out which branch to address.
When I run git config --list
I get a lot of branch settings that indicate the upstream for those branches but they don't seem to mean what "remote difference against master" means in my head.
Example:
branch.test-branch.remote=origin
branch.test-branch.merge=refs/heads/test-branch
@whereami8224 are you sure the branch.x.{remote,merge}
do what you think they do?
I'm thinking:
branch.<name>.remote
as the remote. .git/.radar_tracking_master
or something similar (naming is hard). If the file doesn't exist assume master
and create it. git-radar track <branch>
.That should support multiple remotes and working in a git-flow style in some of your repos. We could even provide a GIT_RADAR_DEFAULT_TRACKING_BRANCH
env var for people who really don't use master ever.
Yeah, my change uses what @whereami8224 brought up (though I didn't know about @{upstream}
). I just used the git config
to suss out the remote tracking branch for the current branch.
Using @{upstream}
should work in this case, I think. It might even be better than what I did in #74 though it does fail when there's no upstream branch. There would need to be a guard around it.
You could use git config
to grab the values from the gitflow config for comparison:
; git config --get gitflow.branch.develop
develop
; git config --get gitflow.branch.master
master
@michaeldfallen: Yup, quite sure. It's spelled out in the man pages. @slackorama is correct, though, that they don't always get set. They are always set when git branch -t is used, and -t is set by default only when the source branch is a remote tracking branch. (If you set -t and the source branch is local, then branch.x.remote gets set to ".".) So a caveat of using @{upstream} is that local branches based on another local branch won't have a tracking branch by default, and therefore no @{upstream}.
@{upstream}, e.g. master@{upstream}, @{u} The suffix @{upstream} to a branchname (short form @{u}) refers to the branch that the branch specified by branchname is set to build on top of (configured with branch. .remote and branch. .merge). A missing branchname defaults to the current one.
-t --track When creating a new branch, set up branch.
.remote and branch. .merge configuration entries to mark the start-point branch as "upstream" from the new branch. This configuration will tell git to show the relationship between the two branches in git status and git branch -v. Furthermore, it directs git pull without arguments to pull from the upstream when the new branch is checked out. This behavior is the default when the start point is a remote-tracking branch. Set the branch.autoSetupMerge configuration variable to false if you want git checkout and git branch to always behave as if --no-track were given. Set it to always if you want this behavior when the start-point is either a local or remote-tracking branch.
Some digging around in a few of my repos / branches shows me that git rev-parse @{upstream}
fails pretty often with fatal: no upstream configured for branch
on a lot of my branches. Seems that by default, git checkout -b
doesn't set up the tracking even if the source branch had tracking. @whereami8224 let me know if I'm doing something wonky or misunderstood the @{upstream} idea
> git clone git@github.com:michaeldfallen/git-radar.git
Cloning into 'git-radar'...
cd remote: Counting objects: 862, done.
remote: Total 862 (delta 0), reused 0 (delta 0), pack-reused 862
Receiving objects: 100% (862/862), 451.74 KiB | 0 bytes/s, done.
Resolving deltas: 100% (525/525), done.
-Checking connectivity... done.
> cd git-radar/
git:(master) > git rev-parse @{upstream}
c67d6bcd88c9073bc072af1cb13d7bfa85cbbbb0
git:(master) > git checkout -b test_branch
Switched to a new branch 'test_branch'
git:(upstream ⚡ test_branch) > git rev-parse @{upstream}
fatal: no upstream configured for branch 'test_branch'
Rather than try to enforce certain daily workflows in git. I think I favor the one-time config approach. To @slackorama's point, we could even try to infer the correct branch from gitflow.branch.develop
. How about this:
diff --git a/radar-base.sh b/radar-base.sh
index a9e3a7f..8c966c8 100755
--- a/radar-base.sh
+++ b/radar-base.sh
@@ -264,9 +264,24 @@ commits_ahead_of_remote() {
fi
}
+tracked_remote() {
+ config_branch="$(git config --get gitradar.trackingbranch)"
+ if [[ -n "$config_branch" ]]; then
+ printf '%s' "$config_branch"
+ return 0
+ fi
+ config_branch="$(git config --get gitflow.branch.develop)"
+ if [[ -n "$config_branch" ]]; then
+ printf 'origin/%s' "$config_branch"
+ return 0
+ fi
+ printf "origin/master"
+ return 0
+}
remote_behind_of_master() {
remote_branch=${1:-"$(remote_branch_name)"}
- tracked_remote="origin/master"
+ tracked_remote="$(tracked_remote)"
if [[ -n "$remote_branch" && "$remote_branch" != "$tracked_remote" ]]; then
git rev-list --left-only --count ${tracked_remote}...${remote_branch} 2>/dev/null || printf '%s' "0"
else
@@ -276,7 +291,7 @@ remote_behind_of_master() {
remote_ahead_of_master() {
remote_branch=${1:-"$(remote_branch_name)"}
- tracked_remote="origin/master"
+ tracked_remote="$(tracked_remote)"
if [[ -n "$remote_branch" && "$remote_branch" != "$tracked_remote" ]]; then
git rev-list --right-only --count ${tracked_remote}...${remote_branch} 2>/dev/null || printf '%s' "0"
else
If this directionally looks good to folks I'll submit a PR for code style comments
To play devil's advocate however, I'm noticing that the prompt itself expects a real upstream to be set (thus the upstream ⚡
part of my prompt). Maybe I just need to set branch.autosetupmerge
and use @{upstream}
. Thoughts?
git:(master) > git rev-parse --abbrev-ref @{upstream}
origin/master
git:(master) > git checkout -b test
Switched to a new branch 'test'
git:(upstream ⚡ test) > git rev-parse --abbrev-ref @{upstream}
fatal: no upstream configured for branch 'test'
git:(upstream ⚡ test) > git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
git:(master) > git config branch.autosetupmerge always
git:(master) > git checkout -b test2
Branch test2 set up to track local branch master.
Switched to a new branch 'test2'
git:(test2) > git rev-parse --abbrev-ref @{upstream}
master
@johnboiles no, I think you have it right. @{upstream} is probably not the panacea I originally thought it was.
Any progress on this? My team is using git-flow, and we would really like to set up the remote branch to compare to to be origin/develop
instead of origin/master
Currently
origin/master
is hardcoded. To support git-flow we should really be able to configure this. A file in .git that contains the ref to target (defaulted toorigin/master
if not present) should do the job.