Thu, 03 Oct 2013 18:01:21 +0200 largefiles: fix profile of unused largefilesdirstate._ignore
Mads Kiilerich <madski@unity3d.com> [Thu, 03 Oct 2013 18:01:21 +0200] rev 21085
largefiles: fix profile of unused largefilesdirstate._ignore
Tue, 08 Apr 2014 00:48:36 +0200 largefiles: import whole modules instead of importing parts of them
Mads Kiilerich <madski@unity3d.com> [Tue, 08 Apr 2014 00:48:36 +0200] rev 21084
largefiles: import whole modules instead of importing parts of them Be more friendly to demandimport.
Thu, 18 Apr 2013 18:56:18 +0200 largefiles: update should only create a .orig backup of a largefile once
Mads Kiilerich <madski@unity3d.com> [Thu, 18 Apr 2013 18:56:18 +0200] rev 21083
largefiles: update should only create a .orig backup of a largefile once A .orig of a standin after the update do that a .orig of the actual largefile is created. The .orig standin was however never removed again and the largefile .orig was thus overwritten again and again. The fix: remove the standin .orig when it is used.
Mon, 07 Apr 2014 02:12:28 +0200 merge: let manifestmerge emit 'keep' actions when keeping wd version
Mads Kiilerich <madski@unity3d.com> [Mon, 07 Apr 2014 02:12:28 +0200] rev 21082
merge: let manifestmerge emit 'keep' actions when keeping wd version Such a 'keep' action will later be the preferred (non)action when there is multiple ancestors. It is thus very convenient to have it explicitly. The extra actions will only be emitted in the case where the local file has changed since the ancestor but the other hasn't. That is the symmetrical operation to a 'get' action. This will create more action tuples that not really serve a purpose. The number of actions will however have the number of changed files as upper bound and it should thus not increase the memory/cpu use significantly.
Sun, 06 Apr 2014 13:39:51 +0200 merge: pass merge ancestor to calculateupdates as a list
Mads Kiilerich <madski@unity3d.com> [Sun, 06 Apr 2014 13:39:51 +0200] rev 21081
merge: pass merge ancestor to calculateupdates as a list The list will so far always have one element.
Sun, 06 Apr 2014 13:39:51 +0200 merge: move ancestor selection tweaking from manifestmerge to update function
Mads Kiilerich <madski@unity3d.com> [Sun, 06 Apr 2014 13:39:51 +0200] rev 21080
merge: move ancestor selection tweaking from manifestmerge to update function - passing it through calculateupdates. This will make sure manifestmerge actually use the ancestor it is given.
Thu, 03 Oct 2013 18:01:21 +0200 match: make it more clear what _roots do and that it ends up in match()._files
Mads Kiilerich <madski@unity3d.com> [Thu, 03 Oct 2013 18:01:21 +0200] rev 21079
match: make it more clear what _roots do and that it ends up in match()._files
Tue, 15 Apr 2014 23:29:19 -0400 cat: explicitly document the supported formatter rules
Matt Harbison <matt_harbison@yahoo.com> [Tue, 15 Apr 2014 23:29:19 -0400] rev 21078
cat: explicitly document the supported formatter rules The previous documentation pointed to the export command, but even if the user recognized that instead of only reading the cat specific list of rules, not all of the export rules applied anyway (specifically %N, %n and %m). The new items are a copy/paste from export's list. These rules have existed since at least version 0.5. Note that %m gets substituted with 'None' because the commit message isn't passed to cmdutil.makefilename(). %R and %r are currently effectively the same, since no revwidth is passed, however they both work. There aren't any existing tests for these rules, so they are added to prevent future regression.
Wed, 16 Apr 2014 01:10:08 +0200 convert: backout 81cf597dafa9 and a3545c3104aa -closemap
Mads Kiilerich <madski@unity3d.com> [Wed, 16 Apr 2014 01:10:08 +0200] rev 21077
convert: backout 81cf597dafa9 and a3545c3104aa -closemap Closemap solves a very specific use case. It would be better to have a more generic solution than to have to maintain this forever. Closemap has not been released yet and removing it now will not break any backward compatibility contract. There is no test coverage for closemap but it seems like the same can be achieved with a simple and much more powerful custom extension: import hgext.convert.hg class source(hgext.convert.hg.mercurial_source): def getcommit(self, rev): c = super(source, self).getcommit(rev) if rev in [''' d643f67092ff123f6a192d52f12e7d123dae229f 9117c6561b0bd7792fa13b50d28239d51b78e51f f368a1c302d5b87506f7edb13769e591e063d7ea ''']: c.extra = c.extra.copy() c.extra['close'] = '1' return c hgext.convert.hg.mercurial_source = source
Wed, 16 Apr 2014 01:09:49 +0200 convert: backout b75a04502ced and 9616b03113ce - tagmap
Mads Kiilerich <madski@unity3d.com> [Wed, 16 Apr 2014 01:09:49 +0200] rev 21076
convert: backout b75a04502ced and 9616b03113ce - tagmap Tagmap solves a very specific use case. It would be better to have a more generic solution than to have to maintain this forever. Tagmap has not been released yet and removing it now will not break any backward compatibility contract. There is no test coverage for tagmap but it seems like the same can be achieved with a (relatively) simple and much more powerful custom extension: import hgext.convert.hg def f(tag): return tag.replace('some', 'other') class source(hgext.convert.hg.mercurial_source): def gettags(self): return dict((f(tag), node) for tag, node in in super(source, self).gettags().items()) def getfile(self, name, rev): data, flags = super(source, self).getfile(name, rev) if name == '.hgtags': data = ''.join(l[:41] + f(l[41:]) + '\n' for l in data.splitlines()) return data, flags hgext.convert.hg.mercurial_source = source
Tue, 15 Apr 2014 11:53:10 -0400 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com> [Tue, 15 Apr 2014 11:53:10 -0400] rev 21075
bundle2: support for push over the wire We use the new method defined in the past changeset to send a bundle2 stream and receive one in reply. The http version is missing remote output support. This will be done later using a bundle part.
Tue, 15 Apr 2014 17:53:52 -0400 httppeer: support for _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com> [Tue, 15 Apr 2014 17:53:52 -0400] rev 21074
httppeer: support for _calltwowaystream This new method is now supported by http too.
Tue, 15 Apr 2014 17:18:35 -0400 sshpeer: add implementation of _calltwowaystream
Pierre-Yves David <pierre-yves.david@fb.com> [Tue, 15 Apr 2014 17:18:35 -0400] rev 21073
sshpeer: add implementation of _calltwowaystream This implements the call needed by bundle2. The error handling is a bit flaky right now, but bundle2 error handling in general is still flaky anyway. Bundle2 is still disabled by default, I do not expect this to be a problem.
Tue, 15 Apr 2014 17:19:46 -0400 wireproto: add a _calltwowaystream method on wirepeer
Pierre-Yves David <pierre-yves.david@fb.com> [Tue, 15 Apr 2014 17:19:46 -0400] rev 21072
wireproto: add a _calltwowaystream method on wirepeer This method will be used by bundle2 pushes. It calls a command, feeds it with a stream and receives another stream in reply. Actual implementation for ssh and http will be done in later changesets.
Tue, 15 Apr 2014 16:49:30 -0400 bundle2: return a bundle20 object from exchanges.unbundle
Pierre-Yves David <pierre-yves.david@fb.com> [Tue, 15 Apr 2014 16:49:30 -0400] rev 21071
bundle2: return a bundle20 object from exchanges.unbundle When a bundle2 is pushed we return a bundle instead of an integer. We use to return a binary stream. We now return a `bundle20` bundler to make the life of wireprotocol implementation simpler.
Tue, 15 Apr 2014 16:42:52 -0400 bundle2: feed a binary stream to `peer.unbundle`
Pierre-Yves David <pierre-yves.david@fb.com> [Tue, 15 Apr 2014 16:42:52 -0400] rev 21070
bundle2: feed a binary stream to `peer.unbundle` This input will have to travel over the wire anyway, so we feed the peer method with a simple binary stream and rely on the server side to use `readbundle` to create the python object. The test output changes because the bundle is created marginally sooner and the debug output interleaves in a different way.
Tue, 15 Apr 2014 15:20:33 -0400 bundle2: allow bundle2 for pulling over the wire
Pierre-Yves David <pierre-yves.david@fb.com> [Tue, 15 Apr 2014 15:20:33 -0400] rev 21069
bundle2: allow bundle2 for pulling over the wire This changeset makes `wireprotocol` peers advertise bundle2 capability and comply with bundle2 `getbundle` requests. Note that advertising bundle2 could make a client try to use it for push. Such pushes would fail. However, I do not expect any human being to have enabled bundle2 on their server yet.
Tue, 15 Apr 2014 11:27:55 -0400 bundle2: return a stream from exchange.getbundle
Pierre-Yves David <pierre-yves.david@fb.com> [Tue, 15 Apr 2014 11:27:55 -0400] rev 21068
bundle2: return a stream from exchange.getbundle For friendliness with the wire protocol implementation, the `exchange.getbundle` now returns a binary stream when asked for a bundle2. We detect a bundle2 request and upgrade the binary stream to an unbundler object. In the future the unbundler may gain feature to look like a binary stream, but we are not quite there yet.
Tue, 15 Apr 2014 13:57:15 -0400 bundle2: let readbundle return unbundle20
Pierre-Yves David <pierre-yves.david@fb.com> [Tue, 15 Apr 2014 13:57:15 -0400] rev 21067
bundle2: let readbundle return unbundle20 The `readbundle` function can now recognize a bundle2 stream and return the appropriate unbundler. This is required for proper bundle2 support over the wire.
Tue, 15 Apr 2014 13:54:54 -0400 bundle2: make header reading optional
Pierre-Yves David <pierre-yves.david@fb.com> [Tue, 15 Apr 2014 13:54:54 -0400] rev 21066
bundle2: make header reading optional The `readbundle` function will consume the 4 first bytes to dispatch between various unbundler. We introduce a way to inform `unbundle20` that the header has been read and it can be trusted.
Tue, 15 Apr 2014 13:42:45 -0400 bundle2: prepare readbundle to return more that one type of bundle
Pierre-Yves David <pierre-yves.david@fb.com> [Tue, 15 Apr 2014 13:42:45 -0400] rev 21065
bundle2: prepare readbundle to return more that one type of bundle We first read 4 bytes to get the `HG10` bytes then we read the compression scheme if this is `HG10`. This prepares the code for the arrival of `HG20` handling.
Mon, 14 Apr 2014 15:45:30 -0400 bundle2: add a ui argument to readbundle
Pierre-Yves David <pierre-yves.david@fb.com> [Mon, 14 Apr 2014 15:45:30 -0400] rev 21064
bundle2: add a ui argument to readbundle The bundle2 unbundler needs a ui argument. We are now passing this information to `readbundle`.
Mon, 14 Apr 2014 15:33:50 -0400 bundle2: move `readbundle` into the `exchange` module
Pierre-Yves David <pierre-yves.david@fb.com> [Mon, 14 Apr 2014 15:33:50 -0400] rev 21063
bundle2: move `readbundle` into the `exchange` module The `readbundle` function is going to understand the bundle2 header. We move the function to a more suitable place before making any other changes.
Mon, 14 Apr 2014 14:46:32 -0400 bundle2: use headerless HG10UN stream in changegroup
Pierre-Yves David <pierre-yves.david@fb.com> [Mon, 14 Apr 2014 14:46:32 -0400] rev 21062
bundle2: use headerless HG10UN stream in changegroup Using `readbundle` in the part handlers creates a circular import hell. We are now using a simple `HG10UN` stream with no header. Some parameters may later be introduced on the part to change parameter. Producers are updated as well.
Thu, 10 Apr 2014 10:53:43 -0700 bundle2: allow using bundle2 for push
Pierre-Yves David <pierre-yves.david@fb.com> [Thu, 10 Apr 2014 10:53:43 -0700] rev 21061
bundle2: allow using bundle2 for push We now support bundle2 for local push. The unbundle function has to detect which version of the bundle to use since the return type is different. Note that push error handling is currently nonexistent. This is one of the reasons why bundle2 is still disabled by default.
Fri, 11 Apr 2014 06:43:01 -0700 bundle2: add a "check:heads" handler
Pierre-Yves David <pierre-yves.david@fb.com> [Fri, 11 Apr 2014 06:43:01 -0700] rev 21060
bundle2: add a "check:heads" handler This part is intended to hold the same role as the `heads` argument of the unbundle function. The client fill it with the known heads at bundle time and the server will abort if its heads changed.
Sun, 13 Apr 2014 16:36:51 -0400 repoview: make the conversion from node to rev explicit while computing hidden
Pierre-Yves David <pierre-yves.david@fb.com> [Sun, 13 Apr 2014 16:36:51 -0400] rev 21059
repoview: make the conversion from node to rev explicit while computing hidden You cannot use `repo[...]` lookup here. 1. It is slow 2. It is very likely to trigger a hidden computation itself, entering an infinite loop.
Sun, 13 Apr 2014 16:39:31 -0400 repoview: drop duplicated lookup
Pierre-Yves David <pierre-yves.david@fb.com> [Sun, 13 Apr 2014 16:39:31 -0400] rev 21058
repoview: drop duplicated lookup We are already looking for local tags on the line above. We can safely drop this extra lookup.
Wed, 16 Apr 2014 09:32:04 -0700 hgweb: adding branch, tags, bookmarks, user, and file list to rss feed entries
Aaron Jensen <ajensen@webmd.net> [Wed, 16 Apr 2014 09:32:04 -0700] rev 21057
hgweb: adding branch, tags, bookmarks, user, and file list to rss feed entries
Wed, 16 Apr 2014 09:31:37 -0700 hgweb: adding branch, tags, bookmarks, user, and file list to atom feed entries
Aaron Jensen <ajensen@webmd.net> [Wed, 16 Apr 2014 09:31:37 -0700] rev 21056
hgweb: adding branch, tags, bookmarks, user, and file list to atom feed entries
Mon, 07 Apr 2014 23:10:20 +0200 patchbomb: warn when emailing a dirty working directory parent
Mads Kiilerich <madski@unity3d.com> [Mon, 07 Apr 2014 23:10:20 +0200] rev 21055
patchbomb: warn when emailing a dirty working directory parent
Wed, 19 Mar 2014 00:19:54 +0100 tests: coverage of convert and filemap include and the default of include all
Mads Kiilerich <madski@unity3d.com> [Wed, 19 Mar 2014 00:19:54 +0100] rev 21054
tests: coverage of convert and filemap include and the default of include all
Wed, 16 Apr 2014 00:37:24 +0900 largefiles: remove no more referred "getoutgoinglfiles()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 16 Apr 2014 00:37:24 +0900] rev 21053
largefiles: remove no more referred "getoutgoinglfiles()"
Wed, 16 Apr 2014 00:37:24 +0900 largefiles: use "outgoinghooks" to avoid redundant outgoing check
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 16 Apr 2014 00:37:24 +0900] rev 21052
largefiles: use "outgoinghooks" to avoid redundant outgoing check Before this patch, "hg outgoing" invokes "findcommonoutgoing()" not only in "commands.outgoing()" but also in "overrides.overrideoutgoing()" (via "getoutgoinglfiles()"), when largefiles is enabled. The latter is redundant. This patch uses "outgoinghooks" to avoid redundant outgoing check. Newly introduced function "overrides.outgoinghook()" is registered into "outgoinghooks" to get the result of outgoing check in "commands.outgoing()". It invokes "lfutil.getlfilestoupload()" directly with the result of outgoing check to avoid redundant outgoing check in "getoutgoinglfiles()": "sort()" is needed, because "lfutil.getlfilestoupload()" doesn't sort the result of it. This patch also omits "if toupload is None" ("No remote repo") case, because failure of looking remote repository up should raise exception in "commands.outgoing()" before invocation of "outgoinghooks". Newly added "hg outgoing --large --graph" tests examine "outgoinghooks" invocations in "hg outgoing --graph" code path.
Wed, 16 Apr 2014 00:37:24 +0900 outgoing: introduce "outgoinghooks" to avoid redundant outgoing check
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 16 Apr 2014 00:37:24 +0900] rev 21051
outgoing: introduce "outgoinghooks" to avoid redundant outgoing check This patch introduces "outgoinghooks" to avoid redundant outgoing check for "hg outgoing" in other than "commands.outgoing" (or utility functions used by it).
Wed, 16 Apr 2014 00:37:24 +0900 hg: make "_outgoing()" return peer object for remote repository
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 16 Apr 2014 00:37:24 +0900] rev 21050
hg: make "_outgoing()" return peer object for remote repository This patch makes "_outgoing()" return peer object for remote repository, to avoid re-execution "expandpath()", "parseurl()", and "peer()" on caller side for specified URL.
Wed, 16 Apr 2014 00:37:24 +0900 hg: make "_outgoing()" return empty list instead of "None"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 16 Apr 2014 00:37:24 +0900] rev 21049
hg: make "_outgoing()" return empty list instead of "None" This patch makes "_outgoing()" return empty list instead of "None", if there are no outgoing changesets, because: - returning "None" requires callers to examine whether returned value is "None" or not explicitly, if callers want to execute loop on returned value, but - there are no explicit needs to return "None"
Wed, 16 Apr 2014 00:37:24 +0900 largefiles: use "summaryremotehooks" to avoid redundant outgoing check
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 16 Apr 2014 00:37:24 +0900] rev 21048
largefiles: use "summaryremotehooks" to avoid redundant outgoing check Before this patch, "hg summary --remote --large" invokes "findcommonoutgoing()" not only in "commands.summary()" but also in "overrides.overridesummary()" (via "getoutgoinglfiles()"). The latter is redundant. This patch uses "summaryremotehooks" to avoid redundant outgoing check. Newly introduced function "overrides.summaryremotehook()" is registered into "summaryremotehooks" to get the result of outgoing check in "commands.summary()". It invokes "lfutil.getlfilestoupload()" directly with the result of outgoing check to avoid redundant outgoing check in "getoutgoinglfiles()".
Wed, 16 Apr 2014 00:37:24 +0900 summary: introduce "summaryremotehooks" to avoid redundant incoming/outgoing check
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 16 Apr 2014 00:37:24 +0900] rev 21047
summary: introduce "summaryremotehooks" to avoid redundant incoming/outgoing check This patch introduces "summaryremotehooks" to avoid redundant incoming/outgoing check for "hg summary" in other than "commands.summary". Only if "--remote" is not specified for "hg summary", hooks registered in "summaryremotehooks" are invoked with "None" as "changes" argument at first, and they should return tuple of two booleans meaning "whether incomings are needed" and "whether outgoings are needed". If no hooks return tuple containing "True", "hg summary" does nothing any more, because incoming/outgoing check is not needed. Otherwise, hooks are invoked again: at this time, "changes" argument refers the result of incoming/outgoing check. This patch also prevents RepoError from being raised if "--remote" is not specified for "hg summary", because of backward compatibility for "hg summary --large" without "--remote".
Wed, 16 Apr 2014 00:37:24 +0900 util: enable "hooks" to return list of the values returned from each hooks
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 16 Apr 2014 00:37:24 +0900] rev 21046
util: enable "hooks" to return list of the values returned from each hooks
Wed, 16 Apr 2014 00:37:24 +0900 summary: separate checking incoming/outgoing and showing remote summary
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 16 Apr 2014 00:37:24 +0900] rev 21045
summary: separate checking incoming/outgoing and showing remote summary This patch separates checking incoming/outgoing and showing remote summary, as a preparation for refactoring in succeeding patches, because: - checking incoming/outgoing may be needed, even if "--remote" is not specified for "hg summary" - checking incoming/outgoing may not be needed simultaneously "hg summary --large" without "--remote" is typical case for these.
Wed, 16 Apr 2014 00:37:24 +0900 largefiles: reuse "findcommonoutgoing()" result at "hg push"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 16 Apr 2014 00:37:24 +0900] rev 21044
largefiles: reuse "findcommonoutgoing()" result at "hg push" Before this patch, "hg push" invokes "findcommonoutgoing()" not only in "exchange.push()" but also in "lfilesrepo.push()", when largefiles is enabled. The latter is redundant. This patch registers own "prepushoutgoinghook" function into "prepushoutgoinghooks" of "localrepository" to reuse "findcommonoutgoing()" result. "prepushoutgoinghook" omits "changelog.nodesbetween()" invocation, because "findcommonoutgoing()" invocation in "exchange.push()" takes "onlyheads" argument and it considers "nodesbetween()".
Wed, 16 Apr 2014 00:37:24 +0900 localrepo: introduce "prepushoutgoinghooks" to extend outgoing check easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 16 Apr 2014 00:37:24 +0900] rev 21043
localrepo: introduce "prepushoutgoinghooks" to extend outgoing check easily This patch introduces "prepushoutgoinghooks" to extend outgoing check before pushing changesets to remote easily. This chooses the function returning "util.hooks" instead of the one to be overridden. The latter may cause problems silently, if one of overriders forgets (or fails) to execute a kind of "super(xxx, self).overridden(...)". In the other hand, the former can ensure that all registered functions are invoked, unless one of them raises an exception.
Wed, 16 Apr 2014 00:37:24 +0900 largefiles: centralize the logic to get outgoing largefiles
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 16 Apr 2014 00:37:24 +0900] rev 21042
largefiles: centralize the logic to get outgoing largefiles Before this patch, "overrides.getoutgoinglfiles()" (called by "overrideoutgoing()" and "overridesummary()") and "lfilesrepo.push()" implement similar logic to get outgoing largefiles separately. This patch centralizes the logic to get outgoing largefiles in "lfutil.getlfilestoupload()". "lfutil.getlfilestoupload()" takes "addfunc" argument, because each callers need different information (and it is useful for enhancement in the future). - "overrides.getoutgoinglfiles()" needs only filenames - "lfilesrepo.push()" needs only hashes of largefiles
Fri, 14 Mar 2014 21:32:05 -0400 cat: support cat with explicit paths in subrepos
Matt Harbison <matt_harbison@yahoo.com> [Fri, 14 Mar 2014 21:32:05 -0400] rev 21041
cat: support cat with explicit paths in subrepos The cat command with an explicit path into a subrepo is now handled by invoking cat on the file, from that subrepo. The previous behavior was to complain that the file didn't exist in the revision (of the top most repo). Now when the file is actually missing, the revision of the subrepo is named instead (though it is probably desirable to continue naming the top level repo). The documented output formatters %d and %p reflect the path from the top level repo, since the purpose of this is to give the illusion of a unified repository. Support for the undocumented (for cat) formatters %H, %R, %h, %m and %r was added long ago (I tested back as far as 0.5), but unfortunately these will reflect the subrepo node instead of the parent context. The previous implementation was a bit loose with the return value, i.e. it would return 0 if _any_ file requested was cat'd successfully. This maintains that behavior.
Thu, 13 Mar 2014 23:45:18 -0400 cat: move most of the implementation into cmdutils.cat()
Matt Harbison <matt_harbison@yahoo.com> [Thu, 13 Mar 2014 23:45:18 -0400] rev 21040
cat: move most of the implementation into cmdutils.cat() This will allow access to the reusable parts from subrepos, similar to add(), forget(), etc.
Tue, 15 Apr 2014 17:51:27 -0400 tests: mark test in tests/test-help.t as contingent on gettext being available
Kent Frazier <kentfrazier@gmail.com> [Tue, 15 Apr 2014 17:51:27 -0400] rev 21039
tests: mark test in tests/test-help.t as contingent on gettext being available
Tue, 15 Apr 2014 16:27:12 -0400 setup.py: fix C extension compilation issue with OS X 10.9 and Xcode 5.1
Kent Frazier <kentfrazier@gmail.com> [Tue, 15 Apr 2014 16:27:12 -0400] rev 21038
setup.py: fix C extension compilation issue with OS X 10.9 and Xcode 5.1
(0) -10000 -3000 -1000 -300 -100 -48 +48 +100 +300 +1000 +3000 +10000 +30000 tip