I have a remote repo cloned in my local computer.
After I make changes to a file, I commit, and then I do this to create a patch:
hg diff -U 8 -p -r PREVIOUS_REVISION_NUMBER file_name > patch_file
I send that patch_file for review.
But I don't see my name or email appearing anywhere in the patch.
My hgrc looks like this :
[ui]
username = My Name <myemail#domain.com>
[extensions]
mq =
[diff]
git = 1
unified = 8
Shouldn't I be seeing my name and email appearing in the patch?
I want further changesets of the remote repo to have my name for this commit, if it does get pushed.
Is there a better way of creating a patch, given my workflow?
(make changes, commit, create patch)
EDIT : I asked because I saw in other people's patches :
# HG changeset patch
# Parent some_long_code
# User name <email>
# Date ....
Don't use hg diff to generate the patch. Use hg export which will add the information that you are expecting as a header at the top of the file including the user and commit message.
Use hg help export for more information.
Shouldn't I be seeing my name and email appearing in the patch?
I don't see why. The patch is a document describing the difference between two files. Your personal identity is not relevant to that difference.
Related
Background: Mercurial Topics
Mercurial has a nice feature call topics as part of the evolve extension. These act as temporary lightweight local branches, and are an integral part of the Heptapod workflow, ensuring nice interactions with Git (via hg-git) for example. They are enabled by include the following in your ~/.hgrc file (or per-repo in .hg/hgrc):
# ~/.hgrc
...
[extensions]
evolve =
topics =
As these are designed for local work, when you push, the topics are not pushed to the server (but become temporary branches in git with the Heptapod workflow).
Question
How can I clone a repo locally to get the topics in my clone?
Part of the answer is to set the source repo to non-publishing: (One should probably do this in the cloned repo to after cloning).
# source_repo/.hg/hgrc
[phases]
publish = false
This keeps the draft phase of the changesets that are part of the topics.
Update: With python==3.9.7, mercurial==6.0.1, and hg-evolve==10.4.1 or higher, this seems to be sufficient. As #Craig points out in the comments, the original issue might have been because I was making the first commit a topic, but this is no longer an issue.
MWE (Old... This seems to work now.)
mkdir a
cd a
touch A.txt
hg init
hg add A.txt
hg topic "A"
hg commit -m "Initial commit of A"
cat > .hg/hgrc <<EOF
[phases]
publish = false
EOF
cd ..
hg clone a b
Now in a, there is a topic A and the commit is in the draft phase (shown by orange colour in the output):
$ hg log -v
changeset: 0:62c4... # orange, indicating draft phase
tag: tip
topic: A
user: Michael <...>
date: Wed ...
files: A.txt
description:
Initial commit of A
while in b, everything is the same, including the draft phase, but no topic:
$ hg log -v
changeset: 0:62c4... # orange, indicating draft phase
tag: tip
user: Michael <...>
date: Wed ...
files: A.txt
description:
Initial commit of A
Consider this a workaround, perhaps, but it should work.
If you're just working locally, you don't actually have to clone. You could just make a full copy of the entire working folder (the folder which contains the .hg folder).
Copy it anywhere you want, then when you run Mercurial commands within that path it will behave exactly like it was cloned, except it won't see your original as the default publishing repo, but instead the same one as your original. You can obviously change this in the .hgrc file if you need to.
Depending on your needs, you might want to do an hg up null beforehand to clear all the local working files, which will speed up the copy for a large repo.
It seems like this was a localized bug. Making the source repo publishing seems to be enough.
# source_repo/.hg/hgrc
[phases]
publish = false
I have read only permission to an hg repo and am trying to develop and test changes to it locally. The problem is that I am in the middle of changing dev machines and am caught in a weird/akward state across the two machines.
On my old machine I made lots of changes to the repo, locslly. I just cloned the repo on my new machine, but obviously that doesn't contain the changes from my old machine. I need a way to createe a patch/diff from my local working copy on my old machine, and then apply them to my local working copy on my new machine. The problem is that I already commited (hg commit -m "Blah") the changes on my old machine to the distributed repo on it.
What set of specific commands can I use to create a patch/diff of my old machine and then apply it to the repo on my new one?
Update
I commited all changes on my old machine and then ran hg serve, exposing http://mymachine.example.com:8000.
On my new machine, where I had made some different changes (locally) than the changes from my old machine, I ran hg pull http://mymachine.example.com:8000 and got:
myuser#mymachine:~/sandbox/eclipse/workspace/myapp$ hg pull http://mymachine.example.com:8000
pulling from http://mymachine.example.com:8000/
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 16 changes to 10 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)
So I run hg merge:
myuser#mymachine:~/sandbox/eclipse/workspace/myapp$ hg merge
abort: uncommitted changes
(use 'hg status' to list changes)
What do I do now?!?
You can use:
$ hg diff > changes.patch
To create a patch file, then:
$ patch -p1 < changes.patch
To apply that patch file on your new machine.
Well, that's actually fantastic, mercurial is a distributed version control system and you do not need to go via any patch file at all: simply pull the changes from your old machine to your new machine:
hg pull URL
where URL can be any network URL or also ssh-login, e.g.
hg pull ssh://mylogin#old.maschine.box or hg pull path/to/old/repository/on/nfs/mount
`
Alternatively you can also use bundle and unbundle. They create bundles which can be imported in the new mercurial easily and keep all meta-information.
hg bundle -r XXX --base YYY > FILENAME
where YYY is a revision you know you have in your new repository. You import it into your new repo with hg unbundle FILENAME. Of course you can bundle several changesets at once by repeating the -r argument or giving a changeset range like -r X:Y.
The least comfortable method is a via diff or export:
hg export -r XXX > FILENAME or equivalent hg diff -c XXX > FILENAME where you need to import the result with patch -p1 < FILENAME or hg import FILENAME.
The easiest way is to do this is to ensure that all work on your old machine is committed. Then use this command on it from the base of your repo:
hg serve
which creates a simple http server on this repo. The monitor should state the name of the http URL it is serving.
On your new machine, just pull from that URL.
Once you've pulled your old changes you can stop the hg serve process with ^C.
The advantages of this method are that it is very quick, and that it works on just about any system. The ssh method is also quick, but it won't work unless your system is configured to use ssh.
Answer to Update
The OPs update is asking an orthogonal question about how to merge changes pulled from a server with local changes. If you haven't already done so, try to digest the information in this merge doc and this one.
Merging is for merging changesets. The error is happening because you have local changes that haven't been committed which mercurial can't merge. So the first thing to do is to commit your local changes, then you will be able to merge.
But before you merge, I strongly recommend that you are merging what you think you are merging. Either ensure there are only 2 heads, or specify which head you are merging with. When merging, you have to be at one of the heads you wish to merge; it's usually better to be at the head with the most changes since the common ancestor because the diffs are simpler.
After you've merged, don't forget to commit the merge. :-)
I'm not sure why but since today I have the problem with pushing my source to repo.
I got abort: no username supplied (see "hg help config")
The thing is that I have [ui] section in hgrc:
[ui]
username = My username
verbose = true
Where's the problem then?
Try doing:
hg --debug showconfig
that shows you all the configuration settings Mercurial is finding and where it's finding them. Since it looks like you're on windows one possibility is BOMs (byte order markers) at the front of your hgrc file. Nodepad likes to incorrectly put them in there.
In a pinch you can always do hg --config ui.username=Whatever_you_want commit, but that's a terrible long term solutions.
Lastly, one expects that error on commit, but you said you're getting it on push. I can't imagine how that could happen.
Either put a hgrc in the .hg directory in your repo or put a hgrc file in your home dir (then it covers all your projects) In the file you should write..
[ui]
username = Your Name <your#mail>
I have directory named "Proyectos" with Django code inside.
I need to commit the project to Source Forge so my teacher can "download" all the code to his computer.
I think I should use some of these address:
http://phone-apps-djan.hg.sourceforge.net:8000/hgroot/phone-apps-djan/phone-apps-djan (read-only)
ssh://lucasab#phone-apps-djan.hg.sourceforge.net/hgroot/phone-apps-djan/phone-apps-djan (read/write)
I did this on Kubuntu:
lucas#lucas-Satellite-L305:~/Desarrollo/Python/Django/Proyectos$ hg clone http://phone-apps-djan.hg.sourceforge.net:8000/hgroot/phone-apps-djan/django-mercurial
but only the folder is created.
I'm a novice and didn't find how to do this. I followed some tutorials but I can't understand a lot of concepts.
I would appreciate some assistance with this, please.
Thanks in advance.
You have two different address to access your Mercurial repository on sourceforge :
http://phone-apps-djan.hg.sourceforge.net:8000/hgroot/phone-apps-djan/phone-apps-djan (read-only), like said after the address, this one is read-only, it is for everyone to clone your project, so they can see the sources and compile / use it. There's no authentication. When you use this address, Mercurial use the HTTP protocol to pull the changes.
ssh://lucasab#phone-apps-djan.hg.sourceforge.net/hgroot/phone-apps-djan/phone-apps-djan (read/write), you can write to your repository through this address, but you have to authenticate yourself (you'll have to enter your password) and Mercurial use the SSH protocol to do that. You can also see your sourceforge username in the address.
First of all, you must do another clone of your project with the second address, otherwise you won't be able to commit. Just cd in a new directory and do :
hg clone ssh://lucasab#phone-apps-djan.hg.sourceforge.net/hgroot/phone-apps-djan/phone-apps-djan
You should be prompted for your sourceforge account password.
Then, you can cd in the newly created directory, do all your changes, add files, etc. When you're done, you can do a hg commitand then a hg push to publish the modification to your repository. If you add new file to the directory don't forget to do a hg add or hg addremove.
You can find a really good and simple tutorial about mercurial on Hg Init, you should read it and try to understand the workflow before doing anything on sourceforge.
Good luck with your project :)
Many thanks to Rob Sobers and Krtek for their answers. I finally could add all my files to SourceForge. I followed their instructions and everything went fine, although I had some minor complications.
This is the answer to my questions step by step:
Over the folder "Proyectos" I did:
hg clone ssh://lucasab#phone-apps-djan.hg.sourceforge.net/hgroot/phone-apps-djan/phone-apps-djan and entered the password for my SourceForge account. A folder "phone-apps-djan" was created.
hg add after I cd into phone-apps-djan and copied all the files of my project into that folder.
hg commit. There was an error at this point: abort: no username supplied (see "hg help config"). So I created a file named .hgrc in my home dir and added these lines:
[ui]
username = my username at sourceforce <the mail address I supplied when registering>
verbose = True
Then I re-entered hg commit.
hg push. The follow error message was displayed: abort: repository default-push not found!. Then I just re-edited the .hgrc file created on the last step and added:
[paths]
default = ssh://lucasab#phone-apps-djan.hg.sourceforge.net/hgroot/phone-apps-djan/phone-apps-dja
I really don't understand what happened here because the .hg directory in my repo already contains a hgrc file with that path :(. Anyway, I did hg push again.
And that was all.
Doing hg clone downloaded the repository to your computer. Now, to update your working directory (so you can work with the files), type hg update.
When you're done making changes, type hg commit to record them. When you're ready upload your changes to SourceForge, type hg push http://path/to/repo. Make sure you push up to the correct repository!
I've seen a number of blog posts, and have experienced for myself, that Mercurial does not preserve the permissions on files pushed from one repo to another. Does anyone know of a Mercurial extension that would preserve the permissions? I'm assuming it can't be done with a hook, because what does a hook know about permissions at the originating repo?
Requested elaboration:
If the only change to a file is a change in permissions (e.g., chmod o+r filename), attempts to commit the file fail with a message saying that the file has not changed.
If I commit a file with permissions 600 (rw-------), then clone the repo, the same file in the clone has permissions 664 (rw-rw-r--):
: nr#yorkie 6522 ; hg clone one two
updating working directory
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
: nr#yorkie 6523 ; ls -l one two
one:
total 4
-rw------- 1 nr nr 8 Aug 18 21:50 foo
two:
total 4
-rw-rw-r-- 1 nr nr 8 Aug 18 21:51 foo
This examples shows that hg clone does not preserve permissions, but hg push does not preserve them either.
In my application, one repo is on a publically accessible path, and it's of major importance that
Multiple users have the right to change the repo
Files in the public repo become readable only when explicitly made readable.
It looks like it can be done using hooks and an auxiliary tool (and a little chewing gum and baling wire):
Get David Hardeman's Metastore, which saves and restores file metadata.
Alter the sources so it will ignore directory .hg as well as .git.
Use the following Mercurial hooks:
precommit.meta = metastore -s
changegroup.update = hg update
update.meta = /usr/unsup/nr/bin/metastore -a
You have to add the .metadata file to the repo.
This lashup will work most of the time, but if you change only permissions and want to propagate it, you'll have to run metastore -s in order to push those changes into the .metadata file where hg will see the change; otherwise the commit thinks nothing is new.
What about using this solution from the Mercurial FAQ:
If you're using Mercurial for config
file management, you might want to
track file properties (ownership and
permissions) too. Mercurial only
tracks the executable bit of each
file.
Here is an example of how to save the
properties along with the files (works
on Linux if you've the acl package
installed):
# cd /etc && getfacl -R . >/tmp/acl.$$ && mv /tmp/acl.$$ .acl
# hg commit
This is far from perfect, but you get the idea. For a more sophisticated solution, check out etckeeper.
For the specific case of the /etc directory, etckeeper looks interesting.
I assumed that metastore was abandonware due to the dead git link on author's site so I whipped the below which is placed directly in repo's .hc/hgrc configuration file:
[paths]
default = ...
[hooks]
# NOTE: precommit is different than pre-commit, see https://www.mercurial-scm.org/repo/hg/help/hgrc for list of hooks
pre-commit =
# export permissions
hg st -camn0 | sort -z | xargs -0 getfacl > .hg.hook.pre-commit.acl.export
hg add .hg.hook.pre-commit.acl.export
# export timestamps
hg st -camn0 | sort -z | xargs -0 stat > .hg.hook.pre-commit.stat.export
hg add .hg.hook.pre-commit.stat.export
update =
# import permissions
setfacl --restore=.hg.hook.pre-commit.acl.export
# import timestamps
# TODO: use touch to restore timestamps
It is not good idea to store permissions in VCS. However, Mercurial supports "executable" flag (that is not the same as permissions, although in Unix executable flag is part of permissions).