michaeldfallen / git-radar

A heads up display for git
MIT License
2.59k stars 85 forks source link

Provide a way to change the remote tracking master branch #3

Open michaeldfallen opened 9 years ago

michaeldfallen commented 9 years ago

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 to origin/master if not present) should do the job.

william26 commented 9 years ago

+1

ryanberckmans commented 9 years ago

+1

donfusilli commented 9 years ago

+1

johnboiles commented 9 years ago

:+1:

whereami8224 commented 9 years ago

Instead of some new config, use the ref @{upstream}. Then it will use the current branch's upstream (specified by config branch..{remote,merge}, which are automatically set when when you branch from a remote tracking branch). Or at least make @{upstream} the default value of your new config option.

aaronmcadam commented 9 years ago

@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.

michaeldfallen commented 9 years ago

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:

  1. we assume remote tracking branch master and use the branch.<name>.remote as the remote.
  2. we store the tracking branch in a .dotfile in .git/.radar_tracking_master or something similar (naming is hard). If the file doesn't exist assume master and create it.
  3. we provide a way to change that, say a command 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.

slackorama commented 9 years ago

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.

slackorama commented 9 years ago

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
whereami8224 commented 9 years ago

@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}.

man git rev-parse
@{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.
man git branch

-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.

johnboiles commented 8 years ago

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
johnboiles commented 8 years ago

If this directionally looks good to folks I'll submit a PR for code style comments

johnboiles commented 8 years ago

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
whereami8224 commented 8 years ago

@johnboiles no, I think you have it right. @{upstream} is probably not the panacea I originally thought it was.

ericbrandwein commented 8 years ago

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