Sublime Forum

Quick way to checkout remote branch after fetch?

#1

Tl;dr:

Basically I’m looking for the Sublime Merge equivalent of the two following CLI commands:

# Reset "feature" to "origin/feature" without checkout
git branch -f feature origin/feature

# Checkout the now up-to-date feature branch
git checkout feature

non-Tl;dr

When I right click a remote branch in the graph view, there’s this option:

This option is very convenient - it creates a branch named feature tracking origin/feature and it performs a checkout of that branch automatically.

However, if a corresponding feature branch tracking origin/feature branch already exists (out of sync with the remote branch, some commits behind), this option doesn’t appear anymore.

This means that in order to work on the latest version of feature, I have to look around the graph view, find the local feature branch which is several commits behind, check it out (which inconveniently changes my work-tree to some old version, potentially interfering with IDE’s), then merge/reset it to sync it with the up-to-date origin/feature branch.

Another option I have is to delete the local feature branch and then use the option pictured above, but that’s a bit awkward.

The Git Extensions client has the following checkbox when you try to checkout a remote branch, which is exactly what I’m looking for:
[x] Reset local branch with the name: 'feature'

(it resets the local branch and immediately checks it out meaning you go straight to the up-to-date commit)

Is there anything similar to this in Sublime Merge?

0 Likes

#2

Your request is somewhat similar to Support "git fetch origin branch:branch" & https://github.com/sublimehq/sublime_merge/issues/242.

As far as I know, there isn’t a way to create a custom command that includes branch selection (until plugin support is added). However, you can add a right-click menu item to the branches in the location bar that accomplishes this:

User/Branch.sublime-menu:

[
	{
		"caption": "Reset $branch against origin",
		"command": "git",
		"args": {"argv": ["branch", "-f", "$branch", "origin/$branch"]}
	}
]

Documentation links:

3 Likes

Pull a branch without checking it out
Support "git fetch origin branch:branch"
#3

Thank you for the thorough response! :grinning:

I didn’t know about the menu modifications feature of Sublime Merge, this makes it so much more powerful. This is almost as good as plugins.

Your suggestion is great and it helps a bit but it’s not exactly what I wanted - I want to be able to do that from the commit tree directly. I don’t really like the Location Bar and it’s closed 99% of the time for me.

I’m looking for a kind of Commit.sublime-menu & Remote Branch.sublime-menu hybrid. I want to be able to right click the commit currently pointed at by the remote branch (or several remote branches), have sublime create separate menu entries for each remote branch (with $remote being the remote branch in each entry), have sublime automatically figure out the corresponding local branch for each $remote and call it $local, and then have the entry perform the git branch -f $local $remote command, for each entry.

Did that make any sense?

I guess the current menu modification functionality is not flexible enough for something like that as of now. Hell I’m not even sure plugins could do that - it all depends on how the API will be designed.

1 Like

#4

This should already happen. The commit list right click menu is more complex than at first glance & follows this structure:

  1. Branch.sublime-menu for all local branches at this commit (alphabetical)
  2. Remote Branch.sublime-menu for all remote branches at this commit (alphabetical, submenu prefixed with origin/)
  3. Tag.sublime-menu for all tags at this commit (alphabetical, submenu prefixed with Tag)
  4. ---- (horizontal rule)
  5. Commit.sublime-menu for this commit

Rules:
a. parts 1-3 are all shown as submenus unless there are 2 or less branches/tags at the commit
b. if there are 2 or less, there is a horizontal rule between each menu block
c. part 4 is removed if there are no branches/tags at the commit


Easiest way to make this happen is with git aliases & you’ll be able to use them on the command line as well. This should do something close to what you’re looking for:

git config --global alias.magic '!f() {
	want="${1##origin/}"
	curr="$(git symbolic-ref -q --short HEAD)"
	
	if git show-ref --quiet "refs/heads/$want"; then
		if [ "$want" == "$curr" ]; then
			git pull
		else
			git branch --force "$want" "origin/$want"
		fi
	elif git show-ref --quiet "refs/remotes/origin/$want"; then
		git checkout -b "$want" "origin/$want"
	else
		echo "neither local nor remote branch ($want) exists, failed">&2
		exit 1
	fi
}; f'

And for both Branch.sublime-menu & Remote Branch.sublime-menu:

[
	// force horizontal rule separator to show
	{ "caption": "-", "id": "end" },
	{
		"caption": "Do some magic on $branch",
		"command": "git",
		"args": {"argv": ["magic", "$branch"]}
	}
]
3 Likes

Interactive staging
Add a sequence of git commands
Push current commit to another remote branch
#5

I actually figured out that one on my own, and I actually hoped that Branch.sublime-menu would affect the commit-right click menu like this, but for some reason when I tried it something went wrong and I just gave up and thought it doesn’t behave this way.

I’m at loss of words, thank you so much for taking the time to understand my problem, solve it, and explain how everything works in the process. It’s very appreciated and helpful.

It works perfectly. TIL about ! shell scripts in Git aliases, that’s very cool.

Again, thank you so much! :smiley:

Just one small thing, you forgot git checkout after git branch --force:

git config --global alias.magic '!f() {
	want="${1##origin/}"
	curr="$(git symbolic-ref -q --short HEAD)"
	
	if git show-ref --quiet "refs/heads/$want"; then
		if [ "$want" == "$curr" ]; then
			git pull
		else
			git branch --force "$want" "origin/$want"
			git checkout "$want"
		fi
	elif git show-ref --quiet "refs/remotes/origin/$want"; then
		git checkout -b "$want" "origin/$want"
	else
		echo "neither local nor remote branch ($want) exists, failed">&2
		exit 1
	fi
}; f'
0 Likes

#6

Not a problem! I really enjoy helping others, especially with using awesome products like Sublime Text & Merge.

0 Likes