Wed, 26 Nov 2014 14:54:16 -0800 manifest: fix a bug where working copy file 'add' mark was buggy stable
Pierre-Yves David <pierre-yves.david@fb.com> [Wed, 26 Nov 2014 14:54:16 -0800] rev 23401
manifest: fix a bug where working copy file 'add' mark was buggy Because the same dictionary was used to (1) get node from parent and (2) store annotated version, we could end up with buggy values. For example with a chain of renames: $ hg mv b c $ hg mv a b The value from 'b' would be updated as "<old-a>a", then the value of c would be updated as "<old-b>a'. With the current dictionary sharing this ends up with: '<new-c>' == '<old-a>aa' This value is double-wrong as we should use '<old-b>' and a single 'a'. We now use a read-only value for lookup. The 'test-rename.t' test is impacted because such a chained added file is suddenly detected as such.
Wed, 26 Nov 2014 17:22:09 +0300 merge: be precise about what merged into what in short desc stable
anatoly techtonik <techtonik@gmail.com> [Wed, 26 Nov 2014 17:22:09 +0300] rev 23400
merge: be precise about what merged into what in short desc
Tue, 11 Nov 2014 20:32:10 -0800 docker: add Docker files for running an Apache mod_wsgi server
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 11 Nov 2014 20:32:10 -0800] rev 23399
docker: add Docker files for running an Apache mod_wsgi server I frequently find myself wanting to run hgweb in a production-like environment, with a real HTTP server and multiple WSGI workers. This patch introduces a Docker environment for running Mercurial under Apache + mod_wsgi. With just a few command executions, it is possible to spin up a Docker container running hgweb. The container is tailored for Mercurial developers wanting to run Mercurial from a source checkout. It is **not** meant to be something suitable for production use. The container provides a default hgweb environment with an empty repository that allows pushes. You can thus start a container and push your favorite repository there for quick testing. The container is designed to allow customizations. Users can provide their own hgweb configurations and mount existing directories containing repositories into the container. The behavior of the container and how to control things is documented in the README.rst file.
Mon, 24 Nov 2014 16:17:02 -0800 merge: use None as filename for base in 'both created' conflicts
Martin von Zweigbergk <martinvonz@google.com> [Mon, 24 Nov 2014 16:17:02 -0800] rev 23398
merge: use None as filename for base in 'both created' conflicts Instead of using a file that we know is not in the common ancestor's maniffest, let's use None. This is safe as the only place that cares about the value (applyupdates) already checks if the item exists in the ancestor.
Mon, 24 Nov 2014 16:42:36 -0800 merge: break out "both renamed a -> b" case
Martin von Zweigbergk <martinvonz@google.com> [Mon, 24 Nov 2014 16:42:36 -0800] rev 23397
merge: break out "both renamed a -> b" case We can further limit the scope of the 2-way merge case by breaking out the case where the file was not created from scratch on both sides but rather renamed in the same way (and is therefore a 3-way merge). This involves copying some code, but it makes it clearer which case the "Note:" in the code refers to.
Mon, 24 Nov 2014 16:16:34 -0800 merge: separate out "both created" cases
Martin von Zweigbergk <martinvonz@google.com> [Mon, 24 Nov 2014 16:16:34 -0800] rev 23396
merge: separate out "both created" cases When 'f' is not in 'ma', 'a' will be 'nullid' and all the if/elif conditions that check whether some one nodeid is equal to 'a' will fail, and the else-clause will instead apply. We can make that more explicit by creating a separate 'm' action for the case where 'a' is 'nullid'. While it does mean copying some code, perhaps it makes it a little clearer which codepaths are possible, and which cases the "Note:" in the code refers to. It also lets us make the debug action messages a little more specific.
Mon, 24 Nov 2014 16:11:22 -0800 merge: indent to prepare for next patch
Martin von Zweigbergk <martinvonz@google.com> [Mon, 24 Nov 2014 16:11:22 -0800] rev 23395
merge: indent to prepare for next patch
Tue, 25 Nov 2014 17:30:05 -0600 merge with stable
Matt Mackall <mpm@selenic.com> [Tue, 25 Nov 2014 17:30:05 -0600] rev 23394
merge with stable
Tue, 25 Nov 2014 02:31:52 -0600 factotum: convert Plan 9 quoted string to Python string
David Eckhardt <David.Eckhardt@cs.cmu.edu> [Tue, 25 Nov 2014 02:31:52 -0600] rev 23393
factotum: convert Plan 9 quoted string to Python string
Tue, 25 Nov 2014 02:27:31 -0600 plan9: setup check for current python build
Jeff Sickel <jas@corpus-callosum.com> [Tue, 25 Nov 2014 02:27:31 -0600] rev 23392
plan9: setup check for current python build
Wed, 19 Nov 2014 22:27:55 -0500 add: check for the existence of a file matched inexactly before adding it
Matt Harbison <matt_harbison@yahoo.com> [Wed, 19 Nov 2014 22:27:55 -0500] rev 23391
add: check for the existence of a file matched inexactly before adding it The change in 10697f29af2b created a problem on Windows and OS X: --- /usr/local/mercurial/tests/test-issue660.t +++ /usr/local/mercurial/tests/test-issue660.t.err @@ -47,6 +47,8 @@ Should succeed - shadow removed: $ hg add b + adding b/b + b/b does not exist! Prior to the failing 'hg add', the file 'b/b' was added and committed, then 'b' was recursively deleted from the filesystem, file 'b' was created and the delete was recorded with 'hg rm --after'. This add is attempting to record the existence of file 'b'. A filesystem that is not case sensitive prevents dirstate.walk() from skipping its step 3, and step 3 has the effect of inserting removed files into the walk list. The Linux code doesn't run through step 3, and didn't exhibit the problem. It's not clear why a non case sensitive filesystem triggers step 3, given that the path normalization occurs in step 2. Prior to 10697f29af2b, part of the check here was 'f not in repo.dirstate' instead of 'f not in wctx'. Files in the 'r' state are filtered out of context.__contains__() but not dirstate.__contains__(). Therefore the removed file name wasn't added to the list of files to add when checking against dirstate. That change was to allow removed files to be readded, but adding a file that doesn't exist is nonsensical. If the user specifies a missing file, it will be an exact match and will still fail.
Thu, 20 Nov 2014 22:33:40 -0500 tests: choose the proper environment variable style for the platform
Matt Harbison <matt_harbison@yahoo.com> [Thu, 20 Nov 2014 22:33:40 -0500] rev 23390
tests: choose the proper environment variable style for the platform Windows was printing out 'commit $HG_NODE' instead of the actual hash.
Thu, 20 Nov 2014 20:07:34 -0500 tests: fix another multi-statement hook for Windows
Matt Harbison <matt_harbison@yahoo.com> [Thu, 20 Nov 2014 20:07:34 -0500] rev 23389
tests: fix another multi-statement hook for Windows The double quotes are necessary, otherwise it tries to pipe into a program named 'short'. An '&' could serve as a command separator on Windows instead of ';', but I don't see any obvious way to swap these depending on the platform. In this case though, there really wasn't a need for multiple statements.
Wed, 19 Nov 2014 23:41:40 -0500 run-tests: set a default largefiles usercache in the default hgrc file
Matt Harbison <matt_harbison@yahoo.com> [Wed, 19 Nov 2014 23:41:40 -0500] rev 23388
run-tests: set a default largefiles usercache in the default hgrc file This fixes a test failure introduced in 4be754832829 on Windows and OS X, where the cached largefile wasn't being deleted because the named .cache directory didn't exist. It only existed on Linux because the test suite sets $HOME to the directory of the test being run, and Linux uses $HOME/.cache by default. Most of the other largefiles tests explicitly set this value at the top of their scripts, but test-largefiles-update.t didn't pick that up when it was created. Those scripts that do set a value will override this. We could just set the parameter in the test-largefiles-update.t script, but there are a few other non obvious tests that exercise largefiles too. These largefiles end up being cached in the user's real cache, so proper hygiene dictates that this not be left to each individual test script.
Mon, 24 Nov 2014 09:50:27 -0800 merge: remove obsolete check for untracked files in 'dm' action
Martin von Zweigbergk <martinvonz@google.com> [Mon, 24 Nov 2014 09:50:27 -0800] rev 23387
merge: remove obsolete check for untracked files in 'dm' action Since 0776a6cababe (merge: don't use unknown(), 2012-02-09), untracked files are no longer included in the manifest diff, so there is no need to check exclude them when renaming files for directory moves with the 'dm' action.
Sun, 23 Nov 2014 23:10:34 -0800 merge: remove dead assignment in applyupdates()
Martin von Zweigbergk <martinvonz@google.com> [Sun, 23 Nov 2014 23:10:34 -0800] rev 23386
merge: remove dead assignment in applyupdates()
Fri, 21 Nov 2014 13:06:04 -0800 merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com> [Fri, 21 Nov 2014 13:06:04 -0800] rev 23385
merge: move calculateupdates() before applyupdated() calculateupdates() happens before applyupdates(), so move it before in the code. That also moves it close to manifestmerge(), which is a good location as calculateupdates() is the only caller of manifestmerge().
Mon, 24 Nov 2014 11:28:46 -0800 merge: remove unused variables from _checkcollision()
Martin von Zweigbergk <martinvonz@google.com> [Mon, 24 Nov 2014 11:28:46 -0800] rev 23384
merge: remove unused variables from _checkcollision()
Tue, 25 Nov 2014 18:37:28 +0900 largefiles: avoid exec-bit examination on the platform being unaware of it stable
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Tue, 25 Nov 2014 18:37:28 +0900] rev 23383
largefiles: avoid exec-bit examination on the platform being unaware of it Changeset 24600c9d7f4e introduced the examination of exec bit of largefiles in "hg status --rev REV" case, but it doesn't avoid it on the platform being unaware of exec-bit (e.g. on NTFS of Windows).
Sat, 22 Nov 2014 17:09:04 -0600 merge with stable
Matt Mackall <mpm@selenic.com> [Sat, 22 Nov 2014 17:09:04 -0600] rev 23382
merge with stable
Thu, 20 Nov 2014 16:30:57 -0800 changegroup: fix file linkrevs during reorders (issue4462) stable
Durham Goode <durham@fb.com> [Thu, 20 Nov 2014 16:30:57 -0800] rev 23381
changegroup: fix file linkrevs during reorders (issue4462) Previously, if reorder was true during the creation of a changegroup bundle, it was possible that the manifest and filelogs would be reordered such that the resulting bundle filelog had a linkrev that pointed to a commit that was not the earliest instance of the filelog revision. For example: With commits: 0<-1<---3<-4 \ / --2<--- if 2 and 3 added the same version of a file, if the manifests of 2 and 3 have their order reversed, but the changelog did not, it could produce a filelog with linkrevs 0<-3 instead of 0<-2, which meant if commit 3 was stripped, it would delete that file data from the repository and commit 2 would be corrupt (as would any future pulls that tried to build upon that version of the file). The fix is to make the linkrev fixup smarter. Previously it considered the first manifest that added a file to be the first commit that added that file, which is not true. Now, for every file revision we add to the bundle we make sure we attach it to the earliest applicable linkrev.
Thu, 20 Nov 2014 16:39:32 -0800 merge: consistently use single quotes for non-user-facing strings
Martin von Zweigbergk <martinvonz@google.com> [Thu, 20 Nov 2014 16:39:32 -0800] rev 23380
merge: consistently use single quotes for non-user-facing strings Because I'm getting tired of searching for both 'O' and "O".
Thu, 13 Nov 2014 11:12:47 +0000 localrepo: add a currenttransaction method
Pierre-Yves David <pierre-yves.david@fb.com> [Thu, 13 Nov 2014 11:12:47 +0000] rev 23379
localrepo: add a currenttransaction method This method returnx the current transaction or None: it will allow a cache writer to hook in an existing transaction.
Thu, 13 Nov 2014 11:11:17 +0000 repoview: extract actual hidden cache writing in its own function
Pierre-Yves David <pierre-yves.david@fb.com> [Thu, 13 Nov 2014 11:11:17 +0000] rev 23378
repoview: extract actual hidden cache writing in its own function This will allow the generation of this cache within the transaction. Relying on the transaction will reduce the chance of reader seeing bad cache.
Fri, 21 Nov 2014 13:58:49 +0800 templates: fix broken "less" & "more" links in paper style (issue4460) stable
Anton Shestakov <engored@ya.ru> [Fri, 21 Nov 2014 13:58:49 +0800] rev 23377
templates: fix broken "less" & "more" links in paper style (issue4460) "/search", which is an invalid command in hgweb, was mistakenly used for "[show] more [revsets]" and "[show] less [revsets]" links on search page in templates "paper" (and those which inherit paper, such as coal) before and worked fine until 6e1fbcb18a75, which made hgweb more strict about invalid commands.
Wed, 19 Nov 2014 01:36:17 +0000 push: stop independent usage of bundle2 in syncphase (issue4454) stable
Pierre-Yves David <pierre-yves.david@fb.com> [Wed, 19 Nov 2014 01:36:17 +0000] rev 23376
push: stop independent usage of bundle2 in syncphase (issue4454) The phase-syncing code was using bundle2 if the remote supported it. It was doing so without regard to bundle2 activation on the client. Moreover, the phase push is now properly included in the unified bundle2 push, so having extra code in syncphase should be useless. If the remote is bundle2-enabled, the phases should already be synced. The buggy verification code was leading to a crash when a 3.2 client was pushing to a 3.1 server. The real bundle2 path detected that their versions were incompatible, but the syncphase code failed to, sending an incompatible bundle2 to the server. We drop the useless and buggy code as a result. The "else" clause is de-indented in the process.
Wed, 19 Nov 2014 23:15:07 -0800 dirstate: speed up repeated missing directory checks
Martin von Zweigbergk <martinvonz@google.com> [Wed, 19 Nov 2014 23:15:07 -0800] rev 23375
dirstate: speed up repeated missing directory checks In a mozilla repo with tip at bb3ff09f52fe, hg update tip~1000 && time hg revert -nq -r tip . displays ~4:20 minutes. With tip~100, it runs in ~11 s. With revision 100000, it did not finish in 12 minutes. Revert calls dirstate.status() with a matcher that matches each file in the target revision. The main problem [1] lies in dirstate._walkexplicit(), which looks for matching deleted directories by checking whether each path is prefix of any path in the dirstate. With m files in the dirstate and n files in the target revision that are not in the dirstate, this is clearly O(m*n). Let's improve by keeping a lazily initialized set of all the directories in the dirstate, so the time becomes O(m+n). After this patch, the 4:20 minutes become 5.5 s, while for a single missing path, it slows down from 1.092 s to 1.150 s (best of 4). The >12 min case becomes 5.8 s. [1] A narrower optimization would be to make revert take the fast path for '.' and '--all'.
Wed, 19 Nov 2014 17:07:27 -0800 revert: access status fields by name rather than index
Martin von Zweigbergk <martinvonz@google.com> [Wed, 19 Nov 2014 17:07:27 -0800] rev 23374
revert: access status fields by name rather than index For better readability.
Wed, 19 Nov 2014 18:35:14 +0900 subrepo: remove "_getstorehashcachepath" referred by no other code paths
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 19 Nov 2014 18:35:14 +0900] rev 23373
subrepo: remove "_getstorehashcachepath" referred by no other code paths
Wed, 19 Nov 2014 18:35:14 +0900 subrepo: replace direct file APIs around "writelines" by "vfs.writelines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 19 Nov 2014 18:35:14 +0900] rev 23372
subrepo: replace direct file APIs around "writelines" by "vfs.writelines" This patch also replaces "self._getstorehashcachepath" (building absolute path up) by "self._getstorehashcachename" (building relative path up), because "vfs.writelines" requires relative path.
Wed, 19 Nov 2014 18:35:14 +0900 vfs: add "writelines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 19 Nov 2014 18:35:14 +0900] rev 23371
vfs: add "writelines" This patch allows "writelines" to take "mode" and "notindexed" arguments, because subsequent patch for subrepo requires both.
Wed, 19 Nov 2014 18:35:14 +0900 vfs: add "notindexed" argument to invoke "ensuredir" with it in write mode
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 19 Nov 2014 18:35:14 +0900] rev 23370
vfs: add "notindexed" argument to invoke "ensuredir" with it in write mode This patch uses "False" as default value of "notindexed" argument, even though "vfs.makedir()" uses "True" for it, because "os.mkdir()" doesn't set "_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED" attribute to newly created directories.
Wed, 19 Nov 2014 18:35:14 +0900 subrepo: replace direct file APIs around "readlines" by "vfs.tryreadlines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 19 Nov 2014 18:35:14 +0900] rev 23369
subrepo: replace direct file APIs around "readlines" by "vfs.tryreadlines" This patch also replaces "self._getstorehashcachepath" (building absolute path up) by "self._getstorehashcachename" (building relative path up), because "vfs.tryreadlines" requires relative path. This patch makes "_readstorehashcache()" return "[]" (returned by "vfs.tryreadlines()"), when cache file doesn't exist, even though "_readstorehashcache()" returned '' (empty string) in such case before this patch. "_readstorehashcache()" is invoked only by the code path below in "_storeclean()": for filehash in self._readstorehashcache(path): if filehash != itercache.next(): clean = False break In this case, "[]" and '' don't differ from each other, because both of them cause avoiding iteration of "for loop".
Wed, 19 Nov 2014 18:35:14 +0900 vfs: add "readlines" and "tryreadlines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 19 Nov 2014 18:35:14 +0900] rev 23368
vfs: add "readlines" and "tryreadlines" This patch allows "readlines" and "tryreadlines" to take "mode" argument, because "subrepo" requires to read files not in "rb" (binary, default for vfs) but in "r" (text) mode in subsequent patch.
Wed, 19 Nov 2014 18:35:14 +0900 subrepo: add "_cachestorehashvfs" to handle cache store hash files via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 19 Nov 2014 18:35:14 +0900] rev 23367
subrepo: add "_cachestorehashvfs" to handle cache store hash files via vfs This "vfs" object will be used by subsequent patches to handle cache store hash files without direct file APIs. This patch decorates "_cachestorehashvfs" with "@propertycache" to delay vfs creation, because it is used only for cooperation with other repositories. In this patch, "/" is used as the path separator, even though "self._repo.join" uses platform specific path separator (e.g. "\\" on Windows). But it is reasonable enough, because "store" and other management file handling already include such implementation, and they work well.
Wed, 19 Nov 2014 18:35:14 +0900 subrepo: remove "_calcfilehash" referred by no other code paths
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 19 Nov 2014 18:35:14 +0900] rev 23366
subrepo: remove "_calcfilehash" referred by no other code paths
Wed, 19 Nov 2014 18:35:14 +0900 subrepo: replace "_calcfilehash" invocation by "vfs.tryread"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 19 Nov 2014 18:35:14 +0900] rev 23365
subrepo: replace "_calcfilehash" invocation by "vfs.tryread" "_calcfilehash" can be completely replaced by simple "vfs.tryread" invocation. def _calcfilehash(filename): data = '' if os.path.exists(filename): fd = open(filename, 'rb') data = fd.read() fd.close() return util.sha1(data).hexdigest() Building absolute path "absname" up by "self._repo.join" for files in "filelist" is avoided, because "vfs.tryread" does so internally.
Wed, 19 Nov 2014 18:35:14 +0900 subrepo: replace "os.path.exists" by "exists" via wvfs of the parent
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 19 Nov 2014 18:35:14 +0900] rev 23364
subrepo: replace "os.path.exists" by "exists" via wvfs of the parent Existance of specified "path" should be examined by "exists" via wvfs of the parent repository, because the working directory of the parent repository may be in UTF-8 mode. Wide API should be used via wvfs in such case. In this patch, "/" is used as the path separator, even though "path" uses platform specific path separator (e.g. "\\" on Windows). But it is reasonable enough, because "store" and other management file handling already include such implementation, and they work well.
Wed, 19 Nov 2014 18:35:14 +0900 subrepo: avoid redundant "util.makedirs" invocation
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 19 Nov 2014 18:35:14 +0900] rev 23363
subrepo: avoid redundant "util.makedirs" invocation "util.makedirs" for the (sub-)repository root of "hgsubrepo" is also executed in the constructor of "localrepository", if "create" is True and ".hg" of it doesn't exist. This patch avoids redundant "util.makedirs" invocation in the constructor of "hgsubrepo".
Wed, 19 Nov 2014 08:50:08 -0800 merge: remove confusing comment about --force
Martin von Zweigbergk <martinvonz@google.com> [Wed, 19 Nov 2014 08:50:08 -0800] rev 23362
merge: remove confusing comment about --force manifestmerge() has a piece of code that's roughly: if not force and different: abort else: # if different: old untracked f may be overwritten and lost ... The comment only talks about what happens when 'different' is true, and in combination with the if-block above, that must mean that it is only about what happens when 'force and different'. It seems quite fine that files are overwritten when 'force' is true, so let's remove the comment. As it stands, it can easily be interpreted as a TODO (which is how I interpreted it at first).
Fri, 17 Oct 2014 22:23:06 -0700 phases: read pending data when appropriate
Pierre-Yves David <pierre-yves.david@fb.com> [Fri, 17 Oct 2014 22:23:06 -0700] rev 23361
phases: read pending data when appropriate If we are called by a hook and pending data exists, read those.
Sun, 28 Sep 2014 21:27:48 -0700 bookmark: read pending data when appropriate
Pierre-Yves David <pierre-yves.david@fb.com> [Sun, 28 Sep 2014 21:27:48 -0700] rev 23360
bookmark: read pending data when appropriate If we are called by a hook and pending data exists, read it.
Wed, 12 Nov 2014 16:54:57 +0000 test-bundle2: check visible data in pre/post-transaction hooks
Pierre-Yves David <pierre-yves.david@fb.com> [Wed, 12 Nov 2014 16:54:57 +0000] rev 23359
test-bundle2: check visible data in pre/post-transaction hooks We are about to make bookmarks and phases available for hooks. Therefore we need a witness for this new availability. We introduce the new hooks in a distinct changeset to reduce the noise in the ones with actual changes.
Fri, 17 Oct 2014 22:19:05 -0700 transaction: write pending generated files
Pierre-Yves David <pierre-yves.david@fb.com> [Fri, 17 Oct 2014 22:19:05 -0700] rev 23358
transaction: write pending generated files Such file are generated with a .pending prefix. It is up to the reader to implement the necessary logic for reading pending files. We add a test to ensure pending files are properly cleaned-up in both success and error cases.
Fri, 17 Oct 2014 21:57:32 -0700 transaction: have _generatefile return a boolean
Pierre-Yves David <pierre-yves.david@fb.com> [Fri, 17 Oct 2014 21:57:32 -0700] rev 23357
transaction: have _generatefile return a boolean The function returns True if any files were generated. This will be used to know if any pending files have been written.
Mon, 29 Sep 2014 01:29:08 -0700 transaction: allow generating files with a suffix
Pierre-Yves David <pierre-yves.david@fb.com> [Mon, 29 Sep 2014 01:29:08 -0700] rev 23356
transaction: allow generating files with a suffix This will allow us to generate temporary pending files. Files generated with a suffix are assumed temporary and will be cleaned up at the end of the transaction.
Wed, 19 Nov 2014 09:52:05 -0600 transaction: fix some docstring grammar
Matt Mackall <mpm@selenic.com> [Wed, 19 Nov 2014 09:52:05 -0600] rev 23355
transaction: fix some docstring grammar
Wed, 12 Nov 2014 14:57:41 +0000 transaction: accept a 'location' argument for registertmp
Pierre-Yves David <pierre-yves.david@fb.com> [Wed, 12 Nov 2014 14:57:41 +0000] rev 23354
transaction: accept a 'location' argument for registertmp This will allow generation of temporary files outside of store. This will be useful for bookmarks.
(0) -10000 -3000 -1000 -300 -100 -48 +48 +100 +300 +1000 +3000 +10000 tip