Local-only version of `hg outgoing`? - mercurial

The command
hg outgoing
compares the local repo to the default push location; it accesses the push location to do it.
I'd like to ask the question "have I checked in changes in my local repo since my last hg push?" without having to access the remote repo.
It seems like there might be enough info in the local repo to figure that out; if so, is there a command to determine that?

There isn't a built-in way to do it. Tracking what has been pushed would be slightly tricky because you can push to multiple places. And you can pull from multiple places. So I could push to X then push to Y then pull from Z and my 'hg outgoing X' output is difficult to predict local-only.
That said you could use a command like this:
hg tag --local --force -r tip pushed
That creates a local-only tag pointing to the current tip. If you always run that after pushing you'll always know what was last pushed.
You could create a post-push hook to do that in your .hgrc:
[hook]
post-push = hg tag --local --force -r tip pushed

Related

Remote bookmarks in Mercurial to keep new features separate

I'd like to use bookmarks in Mercurial to share new features with other developers. I have followed the basic workflow as they appear here or here. In short:
$ hg bookmark main
$ hg bookmark feature
$ hg update feature
$ hg commit -m "changes"
$ hg push -B feature
My main problem is that at this point my changes are not separate from the default branch, and if someone else does
$ hg pull
$ hg update
in their working directory, they get my changes, too, which is not intended - I would like them to do hg update feature to get them.
I figure if I then commit something (an empty commit maybe) to main and push that as well, all is well and feature appears separate. But is there a better way achieving the same result?
Mercurial knows the special bookmark #. Attach that to a commit which is updated to by default.
See also the wiki, section 5.

How to not push closed branches

I have created three branches by mistake.
I closed them by command hg commit --close-branch -m "Closing this head".
Then I switched to another branch MVDM-9.
I want to push my changes to a remote repository, but I get this error.
hg push
pushing to ssh://hg#bitbucket.org/Predictix/mvideo-modeler
searching for changes
abort: push creates new remote branches: MVDM-57C, MVDM-57T, MVDM-60!
(use 'hg push --new-branch' to create new remote branches)
MVDM-57C, MVDM-57T, MVDM-60 are the branches which I closed.
How do I resolve the problem?
You have a couple of options here.
First option (safe)
You can just push the revisions you want to push rather than pushing everything. You just use
hg push -r <revision_number>
substituting <revision_number> with the latest revision number that you want to push, and it will then only push that revision and the revisions that went into it.
Second option (dangerous)
If you have never pushed, pulled or copied the branches that you closed to anywhere else and you don't want to keep them for the history and will never use them then you can strip the changes.
Make sure you take a backup clone of your repository before you start doing this because you could easily destroy your existing copy.
You will need to enabled the strip extension first if it's not already enabled, and then the usage is
hg strip -r <revision_number>
This will delete <revision_number> and all its children from the repository, so you need to be careful what revision you select to delete.
If you've got TortoiseHg installed you can do this via the Workbench UI and you can do it a revision at a time until you've got what you want.
You can always use option 1 first, and then after you've pushed the revisions you want up to the remote repo you can strip the unwanted branches from your local copy.

Is it possible to configure the local mercurial repository to always push the current branch?

The push command accepts a -b flag indicating which branch is to be pushed. But the default, without this flag is to push all the branches.
I want to know whether it is possible to change that default. Meaning pushing without the -b flag only pushes the current branch.
Is it possible?
You can fake a command that does something like it:
[alias]
nudge = push --rev .
Which comes from Steve Losh. That pushes the current revision, which is by definition on the current branch and all of its ancestors.
If you wanted to play with fire you could do:
[alias]
push = push --rev .
which would work until it doesn't -- which is to say when any other script or command tries to invoke push and expects it to push everything.
Better to go with nudge.

How to view diff between head of local repository and head of remote repository?

Before I push to a remote repository, I want to see a consolidated diff between the head of my local repository and the head of the repository I'm pushing too. The best way I know of doing this is to hg clone the remote repository, get the revision of the head, then do a diff between my head and that revision. But this is time-consuming. Is there a quick way?
In addition to
$ hg outgoing -p
which I normally use, I'll like to point you to revision sets. That is a query language that you can use with hg diff (and all other commands that lets you specify changesets). So you can implement hg outgoing -p by
$ hg log -r "outgoing()" -p
and you can get a diff between the parent of the first outgoing changeset and the last outgoing changeset with
$ hg diff -r "p1(first(outgoing()))" -r "last(outgoing())"
Finally, the remotebranch extension can maintain local information about the remote branches so that you don't need to use the network to lookup this information. It lets you use
$ hg log -r "not pushed()"
to find the outgoing changesets, but it's much faster since there's no network round trips involved.
If you're looking for a way of getting all the changes you've made that aren't in the remote repository.
$ hg outgoing -p
The -p is optional and reports in the form of a patch, otherwise it reports in the same way a hg log. This is just your changes regardless of whether anybody else has pushed anything to the remote repository.
If you're looking for changes in the remote repository that you don't have then you use
$ hg incoming
Again there's a -p form if you want it.
Neither of these are exactly what you asked for, but I suspect you don't actually want that.
If you really want the difference between your changes and the new head in the remote repo created by someone else, then you'll need to pull their changes over.
hg pull
hg heads # find revision number of new head
hg diff -r 124992 # or whatever the revision number is.

No changes are pushed when using hg-git

I'm trying to get the hg-git extension working under Windows and after hours of fiddling, I finally seem to have it working. However, nothing shows up in my git repository even though the output of hg push reads:
importing Hg objects into Git
creating and sending data
github::refs/heads/master => GIT:8d946209
[command completed successfully Wed Oct 20 15:26:47 2010]
Try issuing the command hg bookmark -f master
(use -f to force an existing bookmark to move)
Then try pushing again.
This works because Hg-Git pushes your bookmarks up to the Git server as branches and will pull Git branches down and set them up as bookmarks. (from the official README.md)
And it seems that just after I asked this, I made a trivial change. This was picked up and pushed. So it seems that you have to wait until you've made a new commit in order for hg-git to pick it up.
I had chosen to 'Initialize this repository with a README'. This meant I ended up with two heads, which I couldn't hg merge because one had a bookmark.
To get pushing working, I had to:
configure hg-git and github remote as per https://blog.glyphobet.net/essay/2029
pull from github and update
force the merge (checking which id to use with hg heads),
commit the merge
add a trivial change to a file (add a space char to the end),
commit, then
move the bookmark to the tip
push to my configured github remote
This ended up with commands as follows (substituting in <x> sections)
hg pull github
hg update
hg merge <revision-id-of-incoming-git-version>
hg addremove
hg commit -m 'merged with github'
# make some trivial change to a file - eg add a space where it doesn't cause harm
hg add <changed-file>
hg commit -m 'trivial change'
hg bookmark -f master
hg push github
make sure you pick the remote revision for the merge above - if you don't it doesn't work!