Implemented error handling on splicemap file when source is
subversion (This checks are similar to when source is hg or git).
The revision string is expected to be of svn:<uuid><path>@<number>
format.
the test case has been enhanced to check this format.
Implemented similar error handling that is done for hg in an earlier revision.
These are:
a. add checking for splicemap file format
b. add checking for each revision string formats
1. Introduced 2 levels of error handling for splicemap files
a. Check the splicemap file for rules which are same across different
types of source repos. This is done through enhancing parsesplicemap
function
b. Check revision string formats. Each repo may have their own format.
This is done usign checkrevformat function
c. Implemented the above two for hg
This makes record work more like import which ignores for instance mail footers
in a patch file.
This also makes it possible for TortoiseHg to preview unapplied patches
containing such footers.
These names were found using Cython; I was completely puzzled until
I searched the rest of the tree. It's icky to mess with another
module's namespace, but ickier yet to do so without a comment :-)
Before this patch, the certificate of the SMTP server for STARTTLS or
SMTPS isn't verified.
This may cause man-in-the-middle security problem (stealing
authentication information), even though SMTP channel itself is
encrypted by SSL.
When "[smtp] tls" is configured as "smtps" or "starttls", this patch:
- uses classes introduced by preceding patches instead of "SMTP" or
"SMTP_SSL" of smtplib, and
- verifies the certificate of the SMTP server, if "[smtp]
verifycert" is configured as other than False
"[smtp] verifycert" can be configured in 3 levels:
- "strict":
This verifies peer certificate, and aborts if:
- peer certification is not valid, or
- no configuration in "[hostfingerprints]" and "[web] cacerts"
This is default value of "[smtp] verifycert" for security.
- "loose":
This verifies peer certificate, and aborts if peer certification is
not valid.
This just shows warning message ("certificate not verified"), if
there is no configuration in "[hostfingerprints]" and "[web]
cacerts".
This is as same as verification for HTTPS connection.
- False(no verification):
Peer certificate is not verified.
This is as same as the behavior before this patch series.
"hg email --insecure" uses "loose" level, and ignores "[web] cacerts"
as same as push/pull/etc... with --insecure.
Ignoring "[web] cacerts" configuration for "hg email --insecure" is
already done in "dispatch._dispatch()" by looking "insecure" up in the
table of command options.
Previously, we opened the log file when creating a repo object. This
was inefficient (not all repo creation is going to result in a need to
log something), but more importantly it broke subrepo updates when used
on NFS.
* perform an update in the master repo that triggers a subrepo clone
* empty subrepo already exists, and has an open, empty blackbox.log file
due to it being opened eagerly/prematurely
* hg decides to blow away the skeletal subrepo (see use of shutil.rmtree
in subrepo._get)
* we crash, due to NFS treating a delete of an open file as really a
rename to a hidden ".nfs" file
Now that we open the blackbox log file on demand, no file exists at the
time the empty subrepo is deleted, so the above problem does not occur.
A repo should not get the configuration from an other repo, so create it with
the global configuration in repo.baseui.
This is done too when recreating a repo. The repo configuration is reread
anyway. And now deleted repo configuration does not persist.
If you actively work with branches, sometimes you need to close old branches
which last commited hundreds revisions ago. After close you will see long
lines in graph visually spoiling history. This sort only moves closed
revisions as close as possible to parents and does not increase storage size
as datesort do.
Upcoming patches will speed dirstate.walk up by not filtering based on the
match function when match.always() is True. For that to work, match.always()
needs to be accurate. Previously it wasn't so for largefiles.
lfutil.splitstandin(f) can be None, and we query the dirstate for that without
checking if it is. This will cause problems with the upcoming move to critbit-
based dicts, since they only support strings as keys.
When a series of commits first adds a file and then removes it,
hg rebase --collapse prompts whether to keep the file or delete it. This is
due to it reusing the branch merge code. In a noninteractive terminal it
defaults to keeping the file, which results in a collapsed commit that is
has a file that should be deleted. This bug resulted in developers accidentally
commiting unintentional changes to our repo twice today, so it's fairly
important to get fixed.
This change allows rebase --collapse to tell the merge code to accept the
latest version every time without prompting.
Adds a test as well.
When a rebase has conflicts and the user uses rebase --continue, the previously
active bookmark was not being made active once again. With this change that
bookmark is made active again, just as if the rebase had never been interrupted.
This changes the rebasestate file format, but should handle old formats correctly.
Since the file is transient, this is even less of a problem.
Adds a test to verify the new behavior. I manually tested continuing rebases
with and without an active bookmark, and with and without being on the bookmark
being rebased.
hg strip -k was using dirstate.rebuild() which reset all the dirstate
entries timestamps to 0. This meant that the next time hg status was
run every file was considered to be 'unsure', which caused it to do
expensive read operations on every filelog. On a repo with >150,000
files it took 70 seconds when everything was in memory. From a cold
cache it took several minutes.
The fix is to only reset files that have changed between the working
context and the destination context.
For reference, --keep means the working directory is left alone during
the strip. We have users wanting to use this operation to store their
work-in-progress as a commit on a branch while they go work on another
branch, then come back later and be able to uncommit that work and
continue working. They currently use 'git reset HARD^' to accomplish
this in git.
cachelfiles jumped through loops to handle merges and modified files ... but it
did apparently no longer have a valid reason to do so. It should just always
make sure that the largefiles referenced from the standins are present - no
matter which actual largefile is stored in the working directory. If there is
no standin then there is nothing to fetch.
The old code usually verified the hash of all largefiles every time this
function was invoked - for examply by 'update'.
This change makes a trivial noop update 5-10 seconds faster on our repo (with
the other 50% spent doing another unnecessary hashing of all largefiles).
Situations where a largefile for some reason wasn't available sometimes caused
wrong largefile content and state. It has mostly been seen when interrupting
download of largefiles ... and when introducing programming errors.
Instead we now make sure to delete the old and wrong largefile. A missing file
is a well-known error condition and much more reasonable way to handle the
situation.
Largefiles can easily become missing - for example if it simply isn't available
or the download fail. It might even be convenient to be able to work that way
in some cases.
But commiting missing largefiles as if they had been 'hg remove'd is plain wrong.
Looking for a (potentially empty) directory was not reliable - both because it
is a reasonable assumption that empty directories can be removed and because it
wasn't created in all cases ... such as when pulling to an existing repository.
Test output is changed in a case where one revision was pulled, but because of
the off-by-one error it thought that 0 revisions were pulled ... and because of
another bug it thus (tried to) fetch largefiles for all revisions.
After this change it no longer reports failure when it failed while trying to
fetch largefiles it shouldn't fetch. Largefiles that it shouldn't fetch but
managed to fetch anyway will now correctly be missing later on.
This change thus resolves some of unexplained test output introduced in
8664d9900884.
After discussion, we've agreed that largefiles for newly pulled heads should
not be cached by default. The use case for this is using largefiles repos
with multiple remote servers (and therefore multiple remote largefiles caches),
where users will be pulling from non-default locations on a regular basis. We
think this use case will be significantly less common than the use case where
all largefiles are stored on the same central server, so the default should be
no caching.
The old behavior can be obtained by passing the --cache-largefiles flag to
pull.
dest.rev() is the same as target when a new rebase is run, but dest
isn't set when rebase --continue is run. Bug introduced in 97aaac321ced,
which fixed issue3685.
This changeset adds a small mention of it in the help to prevent
confusion. This small addition references online help that is easier to
update and improve at release time.
Following Wagner Bruna's advice, this is added in a plain new paragraph
to not invalidate current translation this close to the release.
Mention that Mercurial helps you not do what you've just been warned not
to do, with a reference to the 'phases' help topic (not the 'phase'
command help).
Thanks to Pierre-Yves David <pierre-yves.david@ens-lyon.org> for
motivating this change and Wagner Bruna
<wagner.bruna+mercurial@gmail.com> for advising on how to do it in an
i18n-friendly way.
If the binary hash of the parent node guessed via --outgoing happened
to contain a special revset character (":" was specified in the bug),
the revset parser would abort. Hexlifying the node before passing it
to the revsingle call should fix that.
largefiles tried to create a peer directly with the specified url. That caused
abort: unsupported URL component: "..."
if a revision was specified in the url.
The branch name do not matter for largefiles' use of remote peers. Largefiles
will be shared among all branches anyway.
When changesets referencing largefiles are pushed then the corresponding
largefiles will be pushed too - unless the target already has them. The client
will use statlfile to make sure it only sends largefiles that the target
doesn't have. The server would however on every statlfile check that the
content of the largefile had the expected hash. What should be cheap thus
became an expensive operation that trashed the disk and the cache.
Largefile hashes are already checked by putlfile before being stored on the
server. A server should thus be able to keep its largefile store free of
errors - even more than it can keep revlogs free of errors. Verification should
happen when running 'hg verify' locally on the server. Rehashing every
largefile on every remote stat is too expensive.
Clients will also stat lfiles before downloading them. When the server verified
the hash in stat it meant that it had to read the file twice to serve it.
With this change the server will assume its own hashes are ok without checking
them on every statlfile.
Some consequences of this change:
- in case of server side corruption the problem will be detected by the
existing check on the client side - not on server side
- clients that could upload an uncorrupted largefile when pushing will no
longer magically heal the server (and break hardlinks) - a client will now
only upload its uncorrupted files after the corrupted file has been removed
on the server side
- client side verify will no longer report corruption in files it doesn't have
(Issue3123 discussed related problems - and how they have been fixed.)
6fb54510b150 introduced batching of statlfile, but not all codepaths got
converted.
_getfile gave _stat garbage and got garbage back. The garbage didn't match the
expected error codes and was thus interpreted as success. It could thus end up
trying to fetch a largefile that didn't exist.
Instead we now pass _stat valid input and handle both correct and invalid
output correctly.
This makes the code work as intended ... but it would probably be better if it
didn't abort on missing largefiles, just like it happened to do before.
basestore.get uses util.atomictempfile when checking and receiving a new
largefile ... but the close/discard logic was too clever for largefiles.
Largefiles relied on being able to discard the file and thus prevent it from
being written to the store. That was however too brittle. lfutil.copyandhash
closes the infile after writing to it ... with a 'blecch' comment. The discard
was thus a silent noop, and as a result of that corruption would be detected
... and then the corrupted files would be used anyway.
Instead we now use a tmp file and rename or unlink it after validating it.
A better solution should be implemented ... but not now.
6fb54510b150 introduced batching of statlfile, but not all codepaths got
converted.
'hg verify' with a remotestore could thus crash with
TypeError: 'builtin_function_or_method' object is not iterable
Also, the 'hash' variable was used without assigning to it. Don't use variable
names that collide with Python built-in functions. Instead we use 'expecthash'
as in localstore.
The tests for this issue covers an untested area. The tests happens to also
reveal incorrect attempts at getting non-existing largefiles, bad server side
handling of that, and corruption issues - all to be fixed later.
Override updaterepo() instead of individual methods that may not be called for
each subrepo. Add test.
Based on patch from Matt Harbison.
Changes the order of update-related messages (now largefiles comes before the
global status).
With rebase taking multiple roots it is possible to have revision in the "rebase
domain" not rebased themself. We do not want rebased revision above them to be
detached. We want such revision to be rebased on the nearest rebased ancestors.
This allows to preserve the topology of the rebase set as much a possible
To achieve this we introduce a new state `revignored` which informs
`defineparents` of the situation.
The test in `test-rebase-obsolete.t` was actually wrote and his now fixed.
For a proper behavior of the `--rev` revision we will need another possible
state for revision ignored by rebase. We alter the comparison to `nullmerge`
to match this future lower state too.
When rebase results in an empty a changeset it is "skipped" and no related
changeset is created at all. When we added obsolescence support to rebase (in
cee0a253a56c) it seemed a good idea to use its parent successor as the
successors for such dropped changesets. (see old version of the altered test).
This option was chosen because it seems a good way to hint about were the
dropped changeset "intended" to be. Such hint would have been used by automatic
evolution mechanism to rebase potential unstable children.
However, field testing of this version are not conclusive. It very often leads
to the creation of (totally unfounded) evolution divergence. This changeset
changes this behavior and mark skipped changesets as pruned (obsolete without
successors). This prevents the issue and seems semantically better probably a
win for obsolescence reading tool.
See example bellow for details:
User Babar has five changesets of interest:
- O, its current base of development.
- U, the new upstream
- A and C, some development changesets
- B another development changeset independent from A
O - A - B - C
\
U
Babar decides that B is more critical than the A and C and rebase it first
$ hg rebase --rev B --dest U
B is now obsolete (in lower case bellow). Rebase result, B', is its
successors.(note, C is unstable)
O - A - b - C
\
U - B'
Babar is now done with B', and want to rebase the rest of its history:
$ hg rebase --source A --dest B'
hg rebase process A, B and C. B is skipped as all its changes are already contained
in B'.
O - U - B' - A' - C'
Babar have the expected result graph wise, obsolescence marker are as follow:
B -> B' (from first rebase)
A -> A' (from second rebase)
C -> C' (from second rebase)
B -> ?? (from second rebase)
Before this changeset, the last marker is `B -> A'`. This cause two issues:
- This is semantically wrong. B have nothing to do with A'
- B has now two successors sets: (B',) and (A',). We detect a divergent
rewriting. The B' and A' are reported as "divergent" to Babar, confusion
ensues. In addition such divergent situation (divergent changeset are children
to each other) is tricky to solve.
With this changeset the last marker is `B -> ø`:
- This is semantically better.
- B has a single successors set (B',)
This scenario is added to the tests suite.
Adds a 'hg blackbox' command for viewing the latest entries in the blackbox log.
By default it shows the last 10 entries, but -l allows the user to specify.
Adds a blackbox extension that listens to ui.log() and writes the messages to
.hg/blackbox.log. Future commits will use ui.log() to log commands, unhandled
exceptions, incoming changes, and hooks. The extension defaults to logging
everything, but can be configured via blackbox.track to only log certain events.
Log lines are of the format: "date time user> message"
Example log line:
2013/02/09 08:35:19 durham> 1 incoming changes - new heads: d84ced58aaa
mq was injecting fake tags whenever the revisions were accessible
to the filtering level.
This issue impacts hgweb since it's common to have "secret" mq
patches. As secret changesets are filtered by hgweb, the tags
computation could break.
Editing the history only is possible when the working dir is a descendant of
the revisions to edit. When this happens explain it by writing
abort: %s is not an ancestor of working directory
In some cases, caching largefiles may take a long time (if the user has
pulled a lot of new heads). This patch makes it more clear what is happening,
by showing the number of heads we are caching largefiles for.
Since git v1.7.8.2-327-g926f1dd (the change was first released in git
1.7.10), git does not return non-zero when "git ls-remote --tags ..."
is run and the repository is damaged. This causes the "damaged
repository with missing commit" test in test-convert-git.t to
unexpectedly succeed.
Fix by aborting if git outputs any lines beginning with "error:",
which required adding some subprocess use in convert/git.py.
The slightly obscure --lfa and --lfc only worked as modifiers to --large and
could be combined. The documentation was however not clear what they did.
Instead they now imply --large and the description is updated.
Show messages at a point where the actions have been sorted, thus preparing for
backout of 14f4258e3526.
This makes manifestmerge more of a silent operation, just like 'copies' is.
Indent 'preserving' messages to make them subordinate to the action logging so
they fit in the new context. (The 'preserving' messages are quite redundant and
could also be removed completely.)
Before this changeset, histedit created all new changesets according
phases.new-commit option without any regards for the phases of the original
changesets.
This changeset fix that using the phase of rewritten changeset to decide the
phase of the resulting changeset. In case of reordering or folding, we keep
secret item secret as it seems the safer path.
temporary commit creation are not affected. They are head only and stripped at
the end of the histedit.
As for the resolution of issue3681 (obsolescence cycle prevention), we do not
handle changesets created by edit command.
Have histedit record the hex of the original changeset as already done by:
- graft
- commit --amend
- rebase
My main motivation for adding this is to prevent the creation of obsolescence cycle
(see issue3681).
Note that commit created during edit are not affected yet.
Later commits add two important items to histedit:
- Obsolescence cycle prevention
- Proper phase conservation
Those logics must be applied to all simple operations (pick, edit, mess) and
will require verbose code.
So we introduce a new function that will provide an entry point for this new.
logic.
The function build a closure to have a clear distinction between commit
arguments and data provided to the function to fulfil its logic.
We have all the necessary mechanism to rebase a set with multiple roots, we only
needed a proper handling of this case we preparing and concluding the rebase.
This changeset des that.
Rebase set with multiple root allows some awesome usage of rebase like:
- rebase all your draft on lastest upstream
hg rebase --dest @ --rev 'draft()'
- exclusion of specific changeset during rebase
hg rebase --rev '42:: - author(Babar)'
- rebase a set of revision were multiple roots are later merged
hg rebase --rev '(18+42)::'
Strip will (if it updates) update to the parent of revs[0], where revs are the
roots of the tree that is stripped.
When revs was list(set) it was thus undefined which root parent it would update
to. With sorted(set) it is at least stable what it updates to. (But it is very
possible that another more useful and predictable behaviour could be defined
... such as updating to the tip-most surviving wd ancestor.)
Add sorted() in places found by testing with PYTHONHASHSEED=random and code
inspection.
An alternative to sprinkling sorted() all over would be to change substate to a
custom dict with sorted iterators...
mq assumed that it had to update from qtip to qparent, and instead of updating
from where it was it failed with:
abort: working directory revision is not qtip
In the context of help document on which this patch focuses, the
example repository, which is source of cloning, should be already
histedit-ed, and contain only 3 revisions (rev # 0 to 2). So, not 3,
but 4 revisions should be added to the destination repository of
cloning, if it contains 7 revisions (rev # 0 to 6).
This patch also adds modifier "histedit-ed" to "example repository",
to make context clear.
There is no '633536316234' revision in the example repository. It
should be 'c561b4e977df', according to the revisions in it and
explanation in help document.
Largefiles update would try to copy f to f.orig if there was a .hglf/f.orig .
That is in many many ways very very wrong, but it also caused an abort if f
didn't exist.
Now it only tries to copy f if it exists.
A situation with this case could happen after interrupting an update. Update
would fail with:
abort: No such file or directory: $TESTTMP/f/.hglf/sub2/large6
Update from a merge without using clean is not possible anyway, so this patch
takes a step in the right direction so it gets as far as reporting the right
error.
Problem: 'hg status' with largefiles enabled would walk through all the files
that .hgignore said should be ignored. That made it slow if a lot of files were
.hgignored or the cache was cold.
It seems like there was a reason to this, but other improvements has rendered
this unnecessary.
Solution: .hgignore is now only ignored when that is requested (--ignore).
This is a minimal 'stable' change. There is room for other improvement.
Largefiles revert do for some reason have two lfdirstates and lfdirstatestatus
invocations in one function. The result from the first lfdirstate check was
however not written back to the lfdirstate, and some files was thus checked
twice.
Problem: 'hg status' kept checking largefiles with an unknown state until some
other command wrote the updated dirstate.
Solution: Add missing lfdirstate.write().
The dispatch code now enables filtering of "hidden" changesets globally. The
filter is installed before command and extension invocation. The `--hidden`
switch is now global and disables this filtering for any command.
Code in log dedicated to changeset exclusion is removed as this global filtering
has the same effect.
Simplify core logic by no longer attempting to work around missing
class attributes. Instead always generate the attributes and ignore
the cache if the attributes are missing
If we pass a directory to commit whose only commitable files
are largefiles, the core commit code aborts before finding
the largefiles.
So we do the following:
For directories that only have largefiles as matches,
we explicitly add the largefiles to the matchlist and remove
the directory.
In other cases, we leave the match list unmodified.
Rebase also have a plain `--rev` option used to select the rebase set (as
`--base` or `--source` would). But the content of the --rev option was intended
for the remote repo and is irrelevant for the local rebase operation. We expect
`hg pull --rebase` to stick with the default behavior here:
hg rebase --base . --dest tip(branch(.))
The `rev` option is dropped from the option passed to rebase.
Strip have dedicated work around to solve the same problem, strip is even a
fraction faster without that thanks to simpler update process of the branchcache.
Obsolescence markers can represent this situation just fine. Rewritten
revisions are marked as precursors of the ones creates by
histedit. Unaffected descendants become "unstable".
If obsolescence is not enabled we keep the current behavior of
aborting. This new behavior only applies when obsolete is
enabled and is subject to future discussion and changes.
Obsolescence markers can represent this situation just fine. Rebased
revisions are marked as precursors of the ones create by
rebase. Unrebased descendants becomes "unstable".
If obsolescence is not enabled we keep the current behavior of
aborting. This new behavior only applies when obsolete is
enabled and is subject to future discussion and changes.
Especially the "no default or default-push path set in hgrc" was often very
misleading and didn't give any hint where it actually was looking.
A long error messages is better than several multi-line messages.
The current _branchtags method is a remnant of an older, much larger function.
Its only remaining role is to help MQ to alter the version of branchcache we
store on disk. As MQ mutates the repository it ensures persistent cache does not
contain anything it is likely to alter.
This changeset makes explicit the stable vs volatile part of repository and
reduces the MQ specific code to the computation of this limit. The main
_branchtags code now handles this possible limit in all cases.
This will help to extract the branchmap logic from the repository.
The new code of _branchtags is a bit duplicated, but as I expect major
refactoring of this section I'm not keen to setup factorisation function here.
We also turn the unix domain socket into a class, so that we have a
sensible place to hang its logically related attributes and behaviour.
We'll shortly want to reuse this in other code.
Previously, the inotify server failed to start if .hg/inotify.sock was
a symlink that pointed to a non-existent path. This behaviour does not
seem to make any sense.
Now, if we encounter a broken symlink, we unlink it and continue.
For a repository with over 400,000 commits, rebasing one revision near tip,
this avoids one walk up the DAG, speeding the operation up by around 0.8
seconds.
The check pattern only checked for whitespace between keyword and operator.
Now it also warns:
> x = f(),7
missing whitespace after ,
> x = f()+7
missing whitespace in expression
Before this patch, largefiles extension uses "largefiles: No remote
repo" message not only for "outgoing" as status report, but also for
"summary" as summarized information.
This sharing prevents message translators from inserting white spaces
between "largefiles:" and "No remote repo" in translated message to
align column position of summarized information.
This patch changes output of largefiles for summary to distinguish
from one for outgoing.
This patch puts "no remote repo" into parentheses, because this is not
summarized information.
Before this patch, one of column positioning messages of MQ summary
output is not translatable, and patches are always listed up at fixed
column position like below, when patch queue is not empty:
mq: 1 applied, 1 unapplied
But column positioning messages for other summarized information are
translatable, so other information may be displayed at different
column position on non-English locale environments.
This patch makes column positioning message of MQ summary output
translatable.
When calling qrefresh with filenames, the filenames were being
treated as case-sensistive on case-insensitive file systems.
So 'qrefresh foo' would not match file 'Foo', and it failed silently.
This fix makes it work correctly on case-insensitive file systems.
Previously the matching function was applied directly to the filenames.
Now we apply the matching function through repo.status, which handles
the case logic for us. A side effect of using repo.status is that
if the qrefresh file doesn't exist, there is output stating it
doesn't exist.
Adds a test to an existing mq refresh case test.
The help text shows "-c/--confirm", which implies that -c is an alias
for --confirm. Actually, it is an alias for --cc. Correct the text
by removing -c.
Previously, if one or more largefiles for a repo being converted were not in the
usercache, the convert would abort with a reference to the largefile being
missing (as opposed to the previous patch, where the standin was referenced as
missing). This is because commitctx() tries to copy all largefiles to the
local store, first from the user cache, and if the file isn't found there, from
the working directory. No files will exist in the working directory during a
convert, however. It is not sufficient to force the source repo to be local
before proceeding, because clone and pull do not download largefiles by default.
This is slightly less than ideal because while the conversion will now complete,
it won't be possible to update to revs with missing largefiles unless the user
intervenes manually, because there is no default path pointing back to the
source repo. Ideally these files would be cached during the conversion.
This check could have been done in reposetup.commitctx() instead, but this
ensures the local store directory is created, which is necessary to enable the
standin matcher.
The rm -> 'rm -f' change in the test is to temporarily suppress an error
clearing the cache- as noted, the cache is is not repopulated during convert.
When that is fixed, this can be changed back and the verification errors will
disappear too.
When the rev isn't specified, the standin for the working copy gets read. But
convert doesn't update the working copy for each cset it processes, so there is
no standin and the 'hg convert' would abort complaining about the standin being
missing.
Note that if the largefile is not in the user cache, 'hg convert' complains
about the largefile itself missing from the destination repo.
For some yet-unkown reason, largefile status does not work on
repoproxy. As status is not affected by filtering, we run it unfiltered.
Na'Tosha Bard's view on this issue:
"but, well, largefiles status is kind of an unholy piece of code"
MQ warns when qstatus contains unknown nodes. With changelog filtering,
a node may be unknown because it is filtered. Thus, an unfiltered repo
is used for this check.
The default for the time zone offset in a converted changeset has
always been 0 (UTC). With this patch, the converted changeset is
modified so that the local offset from UTC is specified as the time
zone offset.
The option is specified as the boolean convert.localtimezone (default
False). Example usage:
hg convert -s cvs --config convert.localtimezone=True example-cvs example-hg
IMPORTANT: the patch only applies to conversions from cvs or svn.
The documentation for the option only appears in those two sections
in the convert help text.
Previously, convert aborted upon encountering a git submodule. This patch
changes it so that it now succeeds. It modifies convert_git to manually generate
'.hgsub' and '.hgsubstate' files for each git revision, so as to convert git sub
modules to non-mercurial subrepositories.
Bookmarks persistence still showed a fair amount of its legacy as a
monkeypatching extension. This encapsulates all bookmarks
serialization and parsing in a single class, and offers a single
location where other bookmarks storage engines can be substituted
in. As a result, many files no longer import the bookmarks module,
which strikes me as an encapsulation win.
This doesn't do anything to the current bookmark state yet, but I'm
hoping put that in the bmstore class as well.
Do not pass ui because it contains the configuration of the repo. It is the
same object as repo.ui.
When a repo is passed to hg.peer, the global configuration is read from
repo.baseui.
Before this change, the thread hierarchy looked like this:
PARENT
PATCH1/x
PATCH2/x
PATCH3/x
...
Now it is:
PARENT
PATCH1/x
PATCH2/x
PATCH3/x
...
With an introductory message the behaviour is unchanged:
PARENT
INTRO
PATCH1/x
PATCH2/x
PATCH3/x
...
This only applies to downloading largefiles, and only when no source for the
pull is explicitly provided. The repository itself was properly being pulled
via 'default' previously.
Using --all-largefiles is not necessary on a bare pull to test this (this
existing test is merely a convenience), but it is required to test pulling on
the rebase path.
Note that the errors generated in the --rebase case are because the repo
specified doesn't have the largefiles in its cache (though they are in the user
cache), so the errors are misleading. Specifying --all-largefiles when cloning
to 'b' fixes this, but instead of errors, it reports caching only 5 largefiles
instead of the 9 that come up missing. Likely this is because the largefile
download procedure tries to download missing files for each rev, and some of the
files have standins in more than one rev that gets pulled.
Before this patch, when no files to upload, "hg outgoing --large" and
"hg summary --large" show "no remote repo", even though valid remote
repository is specified.
It is because that "getoutgoinglfiles()" returns None, not only if no
valid remote repository is specified, but also if no files to upload.
This patch makes "getoutgoinglfiles()" return empty list when no files
to upload, and makes largefiles show "no files to upload" message at
that time.
This patch doesn't test "if toupload is None" route in
"overrideoutgoing()", because this route is not executed unless remote
repository becomes inaccessible just before largefiles specific
processing: successful execution of "orig()" means that at least one
of "default", "default-push" or dest is valid one, and that
"getoutgoinglfiles()" never returns None in such cases.
At "hg summary --large" invocation, this patch shows message below:
largefiles: (no files to upload)
This follows the message shown by "hg summary" with MQ:
mq: (empty queue)
The standin matcher only works if the .hglf directory exists (and it won't exist
if 'clone -U' is used, unless --all-largefiles is also specified). Since not
even 'update -r null' will get rid of the standin directory, this ensures that
the standin directory always exists if the repo has the 'largefiles'
requirement. This requirement is only set after a largefile is committed, so
these directories will not be created for repos that have the extension enabled
but have not committed a largefile.
With the standin directory in place, 'lfconvert --to-normal' will now be able to
download the required largefiles when converting a repo that was created with
'clone -U', and whose files are not in the usercache.
The downloadlfiles command could probably be put inside the 'largefiles'
requirement conditional too, but given that the user specified --all-largefiles,
there is likely an expectation to print out the number of largefiles downloaded,
even if it is 0.
The largefile may be missing for various reasons, including that a remote
repository was cloned without the --all-largefiles option. Therefore, it seems
reasonable to attempt to download the missing files and failing that, abort and
indicate the affected file and revision so the user can manually fix the
problem.
Most method added (or overwritten) to repo by largefile works on `repo`
instead of `self`. This currently works without trouble because `self` and
`repo` are likely the same. However this is semantically dubious and this may
cause issue for filtering. `self` may be proxy object different from the `repo`
one.
This changeset fix that and use `self` when applicable.
This changeset fix the problem to use win32mbcs with mercurial 2.3 or
later.
The problem is brought by side effect of modification of
encoding.upper() (changeset 17236:8b2442729eb3) because upper() does
not accept unicode string argument. So wrapped util.normcase() which
uses upper() will fail. In other words, upper() and lower() are
unicode incompatible.
To fix this issue, this changeset adds new wrapper for reversed
conversion (unicode to str) for lower() and upper() to use them
safely.
convert doesn't normalise double slashes in paths. Path normalization
is applied when a path is loaded into filemap and when a file lookup
request is issued to filemap.
It looks like this method missed the updates in 7a899bd0f9c0 (which changed the
preferred discovery method from findcommonincoming() to findcommonoutgoing()),
and 8b2938386599 (which rolls up the outgoing lists into a single object).
Maintain a whitelist of commands to infer the repo for instead. The whitelist
contains those commands that take file(s) in the working dir as arguments.
We do not want hidden revision to block histedit. They are already "dead"
and we do not care about dead orphans. see similar changeset 40db49347807 for
rebase.
When the obsolete feature is enabled, histedit creates obsolescence marker
instead of stripping replaced changesets.
For now, we keep stripping temporary nodes created along the way.
This changeset rewrites the change tracking logic of histedit to record every
operation it does. Tracked operations record the full list of "old" node that
will eventually be removed to the list of new nodes that replace it. Operations
on temporary nodes are tracked too. Dropped changesets are also recorded as an
"old" node replacement by nothing. This logic is similar to the obsolescence
marker one and will be used for this purpose in later commit.
This new logic implies a big amount of change in the histedit code base.
histedit action functions now always return a tuple of
(new-ctx, [list of rewriting operations])
The old `created`, `replaced` and `tmpnodes` are no longer returned and stored
during histedit operation. When such information is necessary it is computed
from the replacement graph. This computation is done in the `processreplacement`
function.
The `replacemap` is also dropped. It is computed at the end of the command from the
graph. The `bootstrapcontinue` methods are altered to compute this different kind of
information.
This new mechanism requires much less information to be written on disk.
Note:
This changes allows a more accurate bookmark movement. bookmark on dropped
changeset are now move of their parent (or replacement of their parent)
instead of their children.
This fix issue3582
We are now checking for any changesets between the previous `parentctx` and the
current working directory parent. If the current working directory parent is
inconsistent, we abort.
This change is useful as it simplifies the --continue process, easing upcoming
changes.
While working on this changeset, I spotted an unhandled corner case. This corner
case is now documented and have an appropriate issue in the tracker (issue3655).
However, the corner case is still unhandled. handling this test case would
required some additional work:
- actually decide what the proper behavior should be:
- change content of "histedit-state" to add missing data necessary to detect
the situation
- add proper testcase,
But leaving the case unhandled is "okay":
- this is not a regression,
- this is not the purpose of the current series,
- the freeze was near and I had more critical stuff to attend to,
- this is a simple but non trivial, (see above)
Bookmarks are updated during qpop and qpush, but they are not updated
during qrefresh. This behaviour makes it hard to work on an evolving
changeset at the head of a branch. qrefresh should update all bookmarks
that point to the refreshed commit with the new nodeid.
When histedit "continue", there is several complicated logic to apply in order to
detect intermediate changeset and concluded pending operation.
This changeset extract this logic in a dedicated function to lighten the main
one. No alteration to the logic is done.
Create a function dedicated to stripping a group of node. All existing
duplicated code is replaced by call to this function.
This new function take care of stripping known and relevant node only.
The old and fragile patching logic is replaced by smart merges (as rebase and
graft do). This should prevents some conflicts and smoother human resolution.
For this purpose the "foldchanges" function is renamed to "applychanges" and
handle a single revision only.
Update the folding code to works in memory instead of applying patches on the
working directory. This is cleaner, faster and prepare the removal of the whole
patching logic.
This new collapse function will probably move into core sooner or later. A lot
of other rewriting operation may benefit from it.
Here, we exclude hidden changesets from a rebase operation. If we
don't, a rewritten version of the hidden changesets will be created
by rebase. Those rewritten versions won't be hidden and will likely
conflict with other rewriting or revive pruned changeset. Moreover,
rewriting hidden revisions will surprise the user.
This change would not be necessary if changelog filtering were
already in core. But it's fairly cheap and helps to increase the
test-suite for such filtering.
Once changelog level filtering is added, hidden changes will be
automatically excluded or included according to the global --hidden
flags. Plain ignoring them is good enough for now.
In collapse mode, that content of state is not suitable to compute obsolescence
markers. We explicitly pass the resulting revision instead and use it as the
successors for all elements of the rebased set.
When obsolescence feature is enabled we now create markers from the rebased
set to the resulting set instead of stripping. The "state" mapping built by
rebase holds all necessary data.
Changesets "deleted" by the rebase are marked "succeeded" by the changeset they
would be rebased one. That the best guess of "successors" we have. Getting a
successors as meaningful as possible is important for automatic resolution of
obsolescence troubles. In other word, emptied changeset will looks collapsed
with their former parents. (see "empty changeset" section of the test if you are
still confused)
At the end of the rebase, rebased changesets are currently stripped. This
behavior will be eventually dropped in favor of obsolescence marker creation.
The main rebase function is already big and branchy enough. This changeset move
the clean-up logic in a dedicated function before we make it more complex.
46cdcb89086f fixed display of non-ASCII names in file-selecting prompt, but
display in chunk selection remained broken. The reason is that using '%r' in
string formatting results in calling `repr` on file names, thus mangling
non-ASCII ones.
This allows the wrapped command's validation code to run (which is currently
only to ensure 'noupdate' and 'updaterev' aren't both specified), the
copy/pasted unpacking of hg.clone() args to be removed, and any future changes
to the base command (however unlikely) to be inherited by largefiles.
Unfortunately, the command override can't be swapped entirely for an hg.clone()
override because the extra --all-largefiles arg needs to be injected. It also
isn't enough to call the wrapped clone command and leave the caching code after
it, because the file caching code needs access to the destination repo, which is
only available from hg.clone(). An alternative would be to use the dest path in
the clone command override to re-obtain a reference to the repo.
A slight deviation from the regular hg.clone() function is that the repo is NOT
deleted if the caching fails, but that was also the previous behavior. Maybe it
should for consistency?
A status message is output if hg.clone() determines the default destination
because None was provided. The previous code never passed None to hg.clone().
Previously, tip would be checked out regardless of the -u or -U parameter. I'm
not sure what the 'required for successful walkchangerevs' comment meant, but it
appears to reference code which has since moved to downloadlfiles() in
5c06bddf85b8. Perhaps it was to force caching when the -U parameter is given?
The price of this change is that -U --all-largefiles won't cache anything. That
will be fixed next.
Note that X + Y in the 'X largefiles updated, n removed' and 'Y additional
largefiles cached' lines do not add up to the same values in these tests, but
all of the largefiles have been downloaded. The reason being that several
largefiles have the same content (eb7338044 is pointed to by sub/large2, large3
and sub/large4). In the 'clone -u 1' operation, this largefile is cached to
populate the working directory, even without --all-largefiles. That means the
file isn't downloaded again and cached in the rev where large3 and sub/large4
both point to this file. Downloading that one file in that one rev seems to be
counted twice with 'clone -u 0'. (Maybe it is also being downloaded twice?)
Avoid mixing popen and subprocess calls, it simplifies the command line
generation and quoting issues with redirections.
In practice, it fixes the subversion sink on Windows and probably helps
with monotone and darcs sources.