* Re: Python extension commands in git - request for policy change
From: Eric S. Raymond @ 2012-11-25 5:18 UTC (permalink / raw)
To: Nguyen Thai Ngoc Duy; +Cc: git, msysGit
In-Reply-To: <CACsJy8BbUjrJtfpEvbcK==Y2gFNsFhFBN93CL36J5uVe=Ca4wQ@mail.gmail.com>
Nguyen Thai Ngoc Duy <pclouds@gmail.com>:
> These may apply to other languages as well. Where do we draw a line?
I'm in favor of the general policy of avoiding scripting languages
other than the top three most widely deployed. At the moment that
means shell, Python, Perl; on present trends, in a few years Perl
(dropping in popularity) might be passed by Ruby on the way up.
Or, to put it another way, I'm *not* actually arguing that we ought
to encourage extension commands in Guile or Haskell or whatever else
the in-language-of-the-week is. It would be bad for maintainability
to fragment git's codebase that way.
What I'm arguing is that the tradeoffs within the group {C, shell, Perl,
Python} have changed in ways that favor Python as it has become more
stable and widely deployed. So instead of grudgingly allowing a few
Python extensions in through a back door we ought to be encouraging
more use of it.
--
<a href="http://www.catb.org/~esr/">Eric S. Raymond</a>
^ permalink raw reply
* Re: Python extension commands in git - request for policy change
From: Nguyen Thai Ngoc Duy @ 2012-11-25 3:15 UTC (permalink / raw)
To: Eric S. Raymond; +Cc: git, msysGit
In-Reply-To: <20121125024451.1ADD14065F@snark.thyrsus.com>
CCing msysgit. I vaguely remember they had problems with building
Python on Windows. I don't know if it's still an issue.
On Sun, Nov 25, 2012 at 9:44 AM, Eric S. Raymond <esr@thyrsus.com> wrote:
> git presently contains one Python extension command, Pete Wycoff's p4
> importer. If my git-weave code is merged it will acquire another.
> I think we can expect more submissions of Python extensions in the
> future, for two good reasons:
>
> 1. Python has a much richer type ontology than shell; there are many
> things this makes relatively easy that are quite painful in shell.
>
> 2. While Perl shares advantage #1, compared to Python it's a
> maintainability mess - much more difficult to read 6 months later.
>
> On the other hand,
>
> 3. Attitudes in the git dev group seem to be influenced by a
> perception that up-to-date Python versions are not as reliably present
> on our target platforms as Perl is.
>
> 4. Python has the disadvantage that comes with robust growth; you have
> to specify "version x.y or later" as a dependency, mainly because new
> modules keep getting getting folded into the stock Python environment.
These may apply to other languages as well. Where do we draw a line?
> Previous conversation on the list suggests that there has been a tacit
> policy of managing these problems by (a) discouraging (though not entirely
> forbidding) Python extensions, and (b) requiring extension submitters to
> document some dependency on language version.
>
> I think this is suboptimal. By not forbidding the Python language
> entirely, we guarantee having to deal with problems 3 and 4 anyway -
> but by discouraging it, we're buying significant long-term
> maintainability costs. It especially disturbed me to hear of Python
> commands being recoded in C - that is definitely not the right
> direction for reducing expected defect counts, if only because of
> memory-management issues.
>
> We're behind the best-practices curve here. The major Linux
> distributions, which have to deal with almost the same set of
> tradeoffs we do, went to Python for pretty much all glue and
> administration scripts outside /etc a decade ago, and the decision has
> served them well.
>
> That, among other things, means up-to-date versions of Python are
> ubiquitous unless we're looking at Windows - in which case Perl and
> shell actually become much bigger portability problems. Mac OS X
> has kept up to date, too; Lion shipped 2.7.1 and that was a major
> release back at this point.
>
> To be fair, there was a time when being a bit twitchy about Python
> version skew and deployment breadth was justified, but I believe that
> time is now well past us. My basis for believing this is very simple -
> I maintain a lot of Python code for systems programmers with stiff
> portability requirements (things like reposurgeon, coverity-submit,
> freecode-submit, shipper, and the Python tools in gpsd). I know what
> kinds of bug reports I get and what kinds I don't, and in the last
> few years "this breaks on my Python version" has gone from unusual
> to doesn't-happen.
>
> I think my experience with gpsd is particularly instructive. Like
> git, that project has a C core with Python wrappers and extension
> components. Like git, it gets deployed in a lot of odd places by people
> who cannot afford the time to be tolerant about cross-platform
> problems and are quite willing to hit the maintainer with a clue-bat
> when they encounter them. The good news is - they don't have to.
>
> I should also point out that none of Mercurial's problems seem to
> have anything to do with the fact that it's written in Python...
>
> I think we can choose a better policy based on some simple premises.
>
> 1) In 2012, we can specify a "floor" Python version of 2.6 (shipped in
> 2008) and be pretty much guaranteed it will be anywhere we want to
> deploy except Windows. Windows will remain a problem because Python
> isn't part of the stock install, but that's an equal or worse problem
> for shell and Perl - and at least the Python project ships a binary
> installer for Windows.
>
> 2) Python extension commands should test the Python version on startup
> and die loudly but gracefully in the rare case that they don't find
> what they need.
>
> 3) We should be unconditionally be encouraging extensions to move
> from shell and Perl to Python. This would be a clear net gain is
> portability and maintainability.
>
> 4) We should be encouraging C code to move to Python, too. There's
> little gain in portability on this path because modern C has cleaned
> up its act a lot, but the drop in expected bug loads would be well
> worth the porting effort. Segfaults are not your friend, and the x2 to
> x5 drop in line count would do very good things for long-term
> maintainability.
> --
> <a href="http://www.catb.org/~esr/">Eric S. Raymond</a>
>
> Live free or die; death is not the worst of evils.
> -- General George Stark.
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Duy
--
*** Please reply-to-all at all times ***
*** (do not pretend to know who is subscribed and who is not) ***
*** Please avoid top-posting. ***
The msysGit Wiki is here: https://github.com/msysgit/msysgit/wiki - Github accounts are free.
You received this message because you are subscribed to the Google
Groups "msysGit" group.
To post to this group, send email to msysgit@googlegroups.com
To unsubscribe from this group, send email to
msysgit+unsubscribe@googlegroups.com
For more options, and view previous threads, visit this group at
http://groups.google.com/group/msysgit?hl=en_US?hl=en
^ permalink raw reply
* Python extension commands in git - request for policy change
From: Eric S. Raymond @ 2012-11-25 2:44 UTC (permalink / raw)
To: git
git presently contains one Python extension command, Pete Wycoff's p4
importer. If my git-weave code is merged it will acquire another.
I think we can expect more submissions of Python extensions in the
future, for two good reasons:
1. Python has a much richer type ontology than shell; there are many
things this makes relatively easy that are quite painful in shell.
2. While Perl shares advantage #1, compared to Python it's a
maintainability mess - much more difficult to read 6 months later.
On the other hand,
3. Attitudes in the git dev group seem to be influenced by a
perception that up-to-date Python versions are not as reliably present
on our target platforms as Perl is.
4. Python has the disadvantage that comes with robust growth; you have
to specify "version x.y or later" as a dependency, mainly because new
modules keep getting getting folded into the stock Python environment.
Previous conversation on the list suggests that there has been a tacit
policy of managing these problems by (a) discouraging (though not entirely
forbidding) Python extensions, and (b) requiring extension submitters to
document some dependency on language version.
I think this is suboptimal. By not forbidding the Python language
entirely, we guarantee having to deal with problems 3 and 4 anyway -
but by discouraging it, we're buying significant long-term
maintainability costs. It especially disturbed me to hear of Python
commands being recoded in C - that is definitely not the right
direction for reducing expected defect counts, if only because of
memory-management issues.
We're behind the best-practices curve here. The major Linux
distributions, which have to deal with almost the same set of
tradeoffs we do, went to Python for pretty much all glue and
administration scripts outside /etc a decade ago, and the decision has
served them well.
That, among other things, means up-to-date versions of Python are
ubiquitous unless we're looking at Windows - in which case Perl and
shell actually become much bigger portability problems. Mac OS X
has kept up to date, too; Lion shipped 2.7.1 and that was a major
release back at this point.
To be fair, there was a time when being a bit twitchy about Python
version skew and deployment breadth was justified, but I believe that
time is now well past us. My basis for believing this is very simple -
I maintain a lot of Python code for systems programmers with stiff
portability requirements (things like reposurgeon, coverity-submit,
freecode-submit, shipper, and the Python tools in gpsd). I know what
kinds of bug reports I get and what kinds I don't, and in the last
few years "this breaks on my Python version" has gone from unusual
to doesn't-happen.
I think my experience with gpsd is particularly instructive. Like
git, that project has a C core with Python wrappers and extension
components. Like git, it gets deployed in a lot of odd places by people
who cannot afford the time to be tolerant about cross-platform
problems and are quite willing to hit the maintainer with a clue-bat
when they encounter them. The good news is - they don't have to.
I should also point out that none of Mercurial's problems seem to
have anything to do with the fact that it's written in Python...
I think we can choose a better policy based on some simple premises.
1) In 2012, we can specify a "floor" Python version of 2.6 (shipped in
2008) and be pretty much guaranteed it will be anywhere we want to
deploy except Windows. Windows will remain a problem because Python
isn't part of the stock install, but that's an equal or worse problem
for shell and Perl - and at least the Python project ships a binary
installer for Windows.
2) Python extension commands should test the Python version on startup
and die loudly but gracefully in the rare case that they don't find
what they need.
3) We should be unconditionally be encouraging extensions to move
from shell and Perl to Python. This would be a clear net gain is
portability and maintainability.
4) We should be encouraging C code to move to Python, too. There's
little gain in portability on this path because modern C has cleaned
up its act a lot, but the drop in expected bug loads would be well
worth the porting effort. Segfaults are not your friend, and the x2 to
x5 drop in line count would do very good things for long-term
maintainability.
--
<a href="http://www.catb.org/~esr/">Eric S. Raymond</a>
Live free or die; death is not the worst of evils.
-- General George Stark.
^ permalink raw reply
* Re: [PATCH] Add documentation on how to integrate commands.
From: Eric S. Raymond @ 2012-11-25 0:06 UTC (permalink / raw)
To: Pete Wyckoff; +Cc: git
In-Reply-To: <20121124151127.GA24459@padd.com>
Working on my revised patch...
Pete Wyckoff <pw@padd.com>:
> Nice start. A few other details; I recently did this for git-p4
> (python).
>
> .gitignore: ignore the auto-generated script, e.g. when
> git-foo.py is built into git-foo.
Added:
3. If your command is implemented in an interpreted language with a
p-code intermediate form, make sure .gitignore in the main directory
includes a pattern entry that ignores such files. Python .pyc and
.pyo files will already be covered.
> INSTALL: note language requirements if odd (see python section)
Added:
4. If your command has dependency on a particular version, document
it in the INSTALL file.
> command-list.txt: categorization of commands for git(1) etc.
Are the values in the right-hand column documented somewhere? What
uses them, and for what purposes.
> RelNotes: Junio generally does this.
Added:
6. When your patch is merged, remind the maintainer to add something
about it in the RelNotes file.
> Also please read Documentation/technical/api-builtin.txt to
> see how to add a built-in command. It also has comments that
> are identical for both built-in and stand-alone command. Could
> be that your text would better go near or with that one, as perhaps
> api-command.txt.
I think this is a good suggestion and will implement it.
If someone can explain the values used in command-list.txt, or (better) point
me to documentation of them, that will enable me to finish the revised patch.
--
<a href="http://www.catb.org/~esr/">Eric S. Raymond</a>
^ permalink raw reply
* Re: [PATCH 0/2] second try
From: Sven Strickroth @ 2012-11-24 19:07 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Jeff King, Jakub Narebski
In-Reply-To: <509FD4F6.5050606@gym-oha.de>
Hi,
Am 11.11.2012 17:40 schrieb Sven Strickroth:
> Am 06.10.2012 20:28 schrieb Junio C Hamano:
>> It is either that it was simply forgotten, or after I wrote the part
>> you quoted early in January there were discussions later that showed
>> the patch was not desirable for some reason. I do not recall which.
>
> I noticed no threads about possible problems, so I try again.
On November 11th I submitted the updated patches again, however, without
any reaction or comments.
git pull git://github.com/csware/git.git gitsvn-askpass
Maybe the reason that this was forgotten was, that the git-svn code was
rearranged and splitted into different files in the past and the code
did not apply cleanly any more.
So, what's the status of this issue? It's now open for nearly one year.
--
Best regards,
Sven Strickroth
PGP key id F5A9D4C4 @ any key-server
^ permalink raw reply
* Re: Know how much to download before clonig
From: Shawn Pearce @ 2012-11-24 18:10 UTC (permalink / raw)
To: arif; +Cc: git
In-Reply-To: <k8qd1l$l7o$1@ger.gmane.org>
On Sat, Nov 24, 2012 at 4:02 AM, arif <aftnix@gmail.com> wrote:
> Is there any way so that i can tell how much i have to download to
> obtain a full clone (not a shallow one) of a respository?
Ask the repository owner to tell you?
There is no information sent by the server about size of repository,
so no, you can't really know without having the repository owner tell
you through some other side channel.
^ permalink raw reply
* Re: Possible vulnerability to SHA-1 collisions
From: Shawn Pearce @ 2012-11-24 18:09 UTC (permalink / raw)
To: Michael Hirshleifer; +Cc: git
In-Reply-To: <50B0AB9C.2040802@caltech.edu>
I don't think there is an issue the way you have tried to describe
this scenario.
On Sat, Nov 24, 2012 at 3:12 AM, Michael Hirshleifer <111mth@caltech.edu> wrote:
> Evil Guy creates 2 files, 1 evil and 1 innocuous, with the same SHA-1
> checksum (including Git header). Mr. Evil creates a local branch with an
> innocuous name like “test-bugfix”, and adds a commit containing a reference
> to the evil file. Separately, using a sockpuppet, Evil Guy creates an
> innocuous bugfix (very likely to be accepted) containing the innocuous file,
> and submits it to Good Guy. Before Good Guy can commit the bugfix, Evil Guy
> pushes the evil branch to Github, and then immediately deletes it; or
> equivalently --force pushes any innocuous commit on top of it. (This is
> unlikely to arouse suspicion, and he can always say he deleted it because it
> didn’t work.)
Here you assume Evil Guy has write access to the same repository as
Good Guy. Lets assume this is possible, e.g. Evil Guy is actually
impersonating White Hat because he managed to steal White Hat's
credentials through a compromised host. Typically Evil Guy doesn't
have write access to Good Guy's repository, and thus can't introduce
objects into it without Good Guy being the one that creates the
objects.
But lets just keep he assumption that Evil Guy can write to the same
repository as Good Guy, and that he managed to create the bad branch
and delete it, leaving the bad object in an unreachable state for 2
weeks.
> Git keeps unreferenced objects around for a few weeks, so when Good Guy
> commits the patch and pushes to Github, an object with an sha1sum that
> matches the good file will already exist in the main repository. Since Git
> keeps the local copy of files when sha1sums match, the main Github
> repository will then contain the evil file associated with Good Guy’s
> commit. Any users cloning from Github will get the evil version. This is an
> exploit.
Typically... Git will fail with an error message when Good Guy pushes.
Good Guy's client will (rightly) believe that the object doesn't exist
on the remote side, after all it is unreachable. So his client will
include it in the pack being transmitted during push. When this pack
arrives on the remote side, the remote will identify it already has an
object named the same as an object coming in the pack. The remote will
do a byte-for-byte compare of both objects. As soon as a single byte
differs, it will abort with an error.
At this point Good Guy can't push to his repository. `git gc
--expire=now` will fix the repository by removing the unreachable
object, at which point Evil Guy's evil object is gone.
> And Good Guy’s local repository will contain the good file; he will not
> notice anything amiss unless he nukes his local repository and clones from
> Github again. Even when the compromise is discovered, there will be no
> reason to suspect Evil Guy; the evil file seems to have been committed by
> Good Guy.
See above. Good Guy would have noticed something is amiss because the
object he sent already existed and didn't match.
> Previous discussion about hash collisions in Git seems to conclude that they
> aren’t a security threat. See
> http://stackoverflow.com/questions/9392365/how-would-git-handle-a-sha-1-collision-on-a-blob/9392525#9392525,
> Linus Torvalds arguing that Git’s security doesn’t depend on SHA-1 collision
> resistance.
This is largely true because there are additional defenses (e.g. the
byte for byte compare on identical objects), and for projects like the
Linux kernel there are many eyes looking at files all of the time.
Anything that is amiss would be announced quickly on LKML and
discussed until the root cause is identified and resolved.
^ permalink raw reply
* Re: [PATCH] Add documentation on how to integrate commands.
From: Eric S. Raymond @ 2012-11-24 15:23 UTC (permalink / raw)
To: Pete Wyckoff; +Cc: git
In-Reply-To: <20121124151127.GA24459@padd.com>
Pete Wyckoff <pw@padd.com>:
> Nice start. A few other details; I recently did this for git-p4
> (python).
>
> .gitignore: ignore the auto-generated script, e.g. when
> git-foo.py is built into git-foo.
>
> INSTALL: note language requirements if odd (see python section)
>
> command-list.txt: categorization of commands for git(1) etc.
>
> RelNotes: Junio generally does this.
>
>
> Also please read Documentation/technical/api-builtin.txt to
> see how to add a built-in command. It also has comments that
> are identical for both built-in and stand-alone command. Could
> be that your text would better go near or with that one, as perhaps
> api-command.txt.
Good points. I will submit a revised patch later today.
--
<a href="http://www.catb.org/~esr/">Eric S. Raymond</a>
^ permalink raw reply
* Re: [PATCH] Add documentation on how to integrate commands.
From: Pete Wyckoff @ 2012-11-24 15:11 UTC (permalink / raw)
To: Eric S. Raymond; +Cc: git
In-Reply-To: <20121124122333.BAD7B4065F@snark.thyrsus.com>
esr@thyrsus.com wrote on Sat, 24 Nov 2012 07:23 -0500:
> +== Integrating a command ==
> +
> +Here are the things you need to do when you want to merge a new
> +subcommand into the git tree.
> +
> +1. Append your command name to one of the variables BUILTIN_OBJS,
> +EXTRA_PROGRAMS, SCRIPT_SH, SCRIPT_PERL or SCRIPT_PYTHON.
> +
> +2. Drop its test in the t directory.
> +
> +That's all there is to it.
Nice start. A few other details; I recently did this for git-p4
(python).
.gitignore: ignore the auto-generated script, e.g. when
git-foo.py is built into git-foo.
INSTALL: note language requirements if odd (see python section)
command-list.txt: categorization of commands for git(1) etc.
RelNotes: Junio generally does this.
Also please read Documentation/technical/api-builtin.txt to
see how to add a built-in command. It also has comments that
are identical for both built-in and stand-alone command. Could
be that your text would better go near or with that one, as perhaps
api-command.txt.
-- Pete
^ permalink raw reply
* [PATCH] Add documentation on how to integrate commands.
From: Eric S. Raymond @ 2012-11-24 12:23 UTC (permalink / raw)
To: git
---
Documentation/CommandIntegration | 69 ++++++++++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
create mode 100644 Documentation/CommandIntegration
diff --git a/Documentation/CommandIntegration b/Documentation/CommandIntegration
new file mode 100644
index 0000000..be248f7
--- /dev/null
+++ b/Documentation/CommandIntegration
@@ -0,0 +1,69 @@
+= Integrating new subcommands =
+
+This is how-to documentation for people who want to add extension
+commands to git.
+
+== Runtime environment ==
+
+git subcommands are standalone executables that live in the git
+execution directory, normally /usr/lib/git-core. The git executable itself
+is a thin wrapper that sets GIT_DIR and passes command-line arguments
+to the subcommand.
+
+(If "git foo" is not found in the git execution directory, the wrapper
+will look in the rest of your $PATH for it. Thus, it's possible
+to write local git extensions that don't live in system space.)
+
+== Implementation languages ==
+
+Most subcommands are written in C or shell. A few are written in
+Perl. A tiny minority are written in Python.
+
+While we strongly encourage coding in portable C for portability, these
+specific scripting languages are also acceptable. We won't accept more
+without a very strong technical case, as we don't want to broaden the
+git suite's required dependencies.
+
+C commands are normally written as single modules, named after the
+command, that link a core library called libgit. Thus, your command
+'git-foo' would normally be implemented as a single "git-foo.c"; this
+organization makes it easy for people reading the code to find things.
+
+See the CodingGuidelines document for other guidance on what we consider
+good practice in C and shell.
+
+== What every extension command needs ==
+
+You must have a man page, written in asciidoc (this is what git help
+followed by your subcommand name will display). Be aware that there is
+a local asciidoc configuration and macros which you should use. It's
+often helpful to start by cloning an existing page and replacing the
+text content.
+
+You must have a test, written to report in TAP (Test Anything Protocol).
+Tests are executables (usually shell scripts) that live in the 't'
+subdirectory of the tree. Each test name begins with 't' and a sequence
+number that controls where in the test sequence it will be executed;
+conventionally the rest of the name stem is that of the command
+being tested.
+
+If your test requires an example repository, create it yourself in the
+test script. There is a test library of shell functions that assists
+wit this; when you use it, the environment is set in a predictable way
+so the author, committer and timestamps are all set to a single well
+known value, allowing git to create a commit that is reproducible on
+all platforms. A test_tick function is used in the scripts to move the
+clock, allowing different times to be used. For an example see
+t7502-commit.sh, or really any script in that directory.
+
+== Integrating a command ==
+
+Here are the things you need to do when you want to merge a new
+subcommand into the git tree.
+
+1. Append your command name to one of the variables BUILTIN_OBJS,
+EXTRA_PROGRAMS, SCRIPT_SH, SCRIPT_PERL or SCRIPT_PYTHON.
+
+2. Drop its test in the t directory.
+
+That's all there is to it.
--
1.7.9.5
--
<a href="http://www.catb.org/~esr/">Eric S. Raymond</a>
The same applies for other kinds of long-lasting low-level pain. [...]
The body's response to being jabbed, pierced, and cut is to produce
endorphins. [...] So here's my programme for breaking that cycle of
dependency on Windows: get left arm tattooed with dragon motif, buy a
crate of Jamaican Hot! Pepper Sauce, get nipples pierced. With any
luck that will produce enough endorphins to make Windows completely
redundant, and I can then upgrade to Linux and get on with things.
-- Pieter Hintjens
^ permalink raw reply related
* Know how much to download before clonig
From: arif @ 2012-11-24 12:02 UTC (permalink / raw)
To: git
Hi,
Is there any way so that i can tell how much i have to download to
obtain a full clone (not a shallow one) of a respository?
--
Cheers
arif
^ permalink raw reply
* Possible vulnerability to SHA-1 collisions
From: Michael Hirshleifer @ 2012-11-24 11:12 UTC (permalink / raw)
To: git
Evil Guy creates 2 files, 1 evil and 1 innocuous, with the same SHA-1
checksum (including Git header). Mr. Evil creates a local branch with an
innocuous name like “test-bugfix”, and adds a commit containing a
reference to the evil file. Separately, using a sockpuppet, Evil Guy
creates an innocuous bugfix (very likely to be accepted) containing the
innocuous file, and submits it to Good Guy. Before Good Guy can commit
the bugfix, Evil Guy pushes the evil branch to Github, and then
immediately deletes it; or equivalently --force pushes any innocuous
commit on top of it. (This is unlikely to arouse suspicion, and he can
always say he deleted it because it didn’t work.)
Git keeps unreferenced objects around for a few weeks, so when Good Guy
commits the patch and pushes to Github, an object with an sha1sum that
matches the good file will already exist in the main repository. Since
Git keeps the local copy of files when sha1sums match, the main Github
repository will then contain the evil file associated with Good Guy’s
commit. Any users cloning from Github will get the evil version. This is
an exploit.
And Good Guy’s local repository will contain the good file; he will not
notice anything amiss unless he nukes his local repository and clones
from Github again. Even when the compromise is discovered, there will be
no reason to suspect Evil Guy; the evil file seems to have been
committed by Good Guy.
Previous discussion about hash collisions in Git seems to conclude that
they aren’t a security threat. See
http://stackoverflow.com/questions/9392365/how-would-git-handle-a-sha-1-collision-on-a-blob/9392525#9392525,
Linus Torvalds arguing that Git’s security doesn’t depend on SHA-1
collision resistance.
This proposed exploit does not involve social engineering, or any good
guys failing to spot or accepting patches containing evil data (what
Good Guy accepts is a genuine bugfix). It contaminates the main public
repository in a way that Good Guy won’t immediately notice. It does not
require a second-preimage attack; Bad Guy creates both versions of the
file. While this does require the bad guy to have commit access, the bad
guy can avoid suspicion after the attack.
^ permalink raw reply
* [PATCH v3] send-email: avoid questions when user has an ident
From: Felipe Contreras @ 2012-11-24 11:16 UTC (permalink / raw)
To: git
Cc: Jeff King, Junio C Hamano, Thomas Rast, Christian Couder,
Stephen Boyd, Ævar Arnfjörð Bjarmason,
Felipe Contreras
Currently we keep getting questions even when the user has properly
configured his full name and password:
Who should the emails appear to be from?
[Felipe Contreras <felipe.contreras@gmail.com>]
And once a question pops up, other questions are turned on. This is
annoying.
The reason it's safe to avoid this question is because currently the
script fails completely when the author (or committer) is not correct,
so we won't even be reaching this point in the code.
The scenarios, and the current situation:
1) No information at all, no fully qualified domain name
fatal: empty ident name (for <felipec@nysa.(none)>) not allowed
2) Only full name
fatal: unable to auto-detect email address (got 'felipec@nysa.(none)')
3) Full name + fqdm
Who should the emails appear to be from?
[Felipe Contreras <felipec@nysa.felipec.org>]
4) Full name + EMAIL
Who should the emails appear to be from?
[Felipe Contreras <felipe.contreras@gmail.com>]
5) User configured
6) GIT_COMMITTER
7) GIT_AUTHOR
All these are the same as 4)
After this patch:
1) 2) won't change: git send-email would still die
4) 5) 6) 7) will change: git send-email won't ask the user
This is good, that's what we would expect, because the identity is
explicit.
3) will change: git send-email won't ask the user
This is bad, because we will try with an address such as
'felipec@nysa.felipec.org', which is most likely not what the user
wants, but the user will get warned by default (confirm=auto), and if
not, most likely the sending won't work, which the user would readily
note and fix.
The worst possible scenario is that such mail address does work, and the
user sends an email from that address unintentionally, when in fact the
user expected to correct that address in the prompt. This is a very,
very, very unlikely scenario, with many dependencies:
1) No configured user.name/user.email
2) No specified $EMAIL
3) No configured sendemail.from
4) No specified --from argument
5) A fully qualified domain name
6) A full name in the geckos field
7) A sendmail configuration that allows sending from this domain name
8) confirm=never, or
8.1) confirm configuration not hitting, or
8.2) Getting the error, not being aware of it
9) The user expecting to correct this address in the prompt
In a more likely scenario where 7) is not the case (can't send from
nysa.felipec.org), the user will simply see the mail was not sent
properly, and fix the problem.
The much more likely scenario though, is where 5) is not the case
(nysa.(none)), and git send-email will fail right away like it does now.
So the likelihood of this affecting anybody seriously is very very slim,
and the chances of this affecting somebody slightly are still very
small. The vast majority, if not all, of git users won't be affected
negatively, and a lot will benefit from this.
Tests-by: Jeff King <peff@peff.net>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
Changes since v2:
* Merge the relevant tests by Jeff King (the rest of the tests might be
useful, but they belong in a separate patch series)
git-send-email.perl | 7 +------
t/t9001-send-email.sh | 5 ++---
2 files changed, 3 insertions(+), 9 deletions(-)
diff --git a/git-send-email.perl b/git-send-email.perl
index aea66a0..503e551 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -748,16 +748,11 @@ if (!$force) {
}
}
-my $prompting = 0;
if (!defined $sender) {
$sender = $repoauthor || $repocommitter || '';
- $sender = ask("Who should the emails appear to be from? [$sender] ",
- default => $sender,
- valid_re => qr/\@.*\./, confirm_only => 1);
- print "Emails will be sent from: ", $sender, "\n";
- $prompting++;
}
+my $prompting = 0;
if (!@initial_to && !defined $to_cmd) {
my $to = ask("Who should the emails be sent to (if any)? ",
default => "",
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index 0351228..f77f68e 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -191,14 +191,13 @@ test_expect_success $PREREQ 'Show all headers' '
test_expect_success $PREREQ 'Prompting works' '
clean_fake_sendmail &&
- (echo "Example <from@example.com>"
- echo "to@example.com"
+ (echo "to@example.com"
echo ""
) | GIT_SEND_EMAIL_NOTTY=1 git send-email \
--smtp-server="$(pwd)/fake.sendmail" \
$patches \
2>errors &&
- grep "^From: Example <from@example.com>\$" msgtxt1 &&
+ grep "^From: A U Thor <author@example.com>\$" msgtxt1 &&
grep "^To: to@example.com\$" msgtxt1
'
--
1.8.0
^ permalink raw reply related
* Re: [PATCH v3 0/7] New remote-bzr remote helper
From: Felipe Contreras @ 2012-11-24 10:21 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Jeff King, Johannes Schindelin, Felipe Contreras
In-Reply-To: <1352643598-8500-1-git-send-email-felipe.contreras@gmail.com>
On Sun, Nov 11, 2012 at 3:19 PM, Felipe Contreras
<felipe.contreras@gmail.com> wrote:
> This is a re-roll of the previous series to add support to fetch and push
> special modes, and refactor some related code.
It seems this one got forgotten, I only see v2 in pu.
Cheers.
--
Felipe Contreras
^ permalink raw reply
* [PATCH] fast-export: Allow pruned-references in mark file
From: Antoine Pelisse @ 2012-11-24 9:47 UTC (permalink / raw)
To: git; +Cc: Antoine Pelisse
fast-export can fail because of some pruned-reference when importing a
mark file.
The problem happens in the following scenario:
$ git fast-export --export-marks=MARKS master
(rewrite master)
$ git prune
$ git fast-export --import-marks=MARKS master
This might fail if some references have been removed by prune
because some marks will refer to non-existing commits.
Let's warn when we have a mark for a commit we don't know.
Also, increment the last_idnum before, so we don't override
the mark.
Signed-off-by: Antoine Pelisse <apelisse@gmail.com>
---
builtin/fast-export.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 12220ad..141b245 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -607,16 +607,19 @@ static void import_marks(char *input_file)
|| *mark_end != ' ' || get_sha1(mark_end + 1, sha1))
die("corrupt mark line: %s", line);
+ if (last_idnum < mark)
+ last_idnum = mark;
+
object = parse_object(sha1);
- if (!object)
- die ("Could not read blob %s", sha1_to_hex(sha1));
+ if (!object) {
+ warning("Could not read blob %s", sha1_to_hex(sha1));
+ continue;
+ }
if (object->flags & SHOWN)
error("Object %s already has a mark", sha1_to_hex(sha1));
mark_object(object, mark);
- if (last_idnum < mark)
- last_idnum = mark;
object->flags |= SHOWN;
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 4/4] tree_entry_interesting: do basedir compare on wildcard patterns when possible
From: Nguyễn Thái Ngọc Duy @ 2012-11-24 4:33 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1353731631-20593-1-git-send-email-pclouds@gmail.com>
Currently we treat "*.c" and "path/to/*.c" the same way. Which means
we check all possible paths in repo against "path/to/*.c". One could
see that "path/elsewhere/foo.c" obviously cannot match "path/to/*.c"
and we only need to check all paths _inside_ "path/to/" against that
pattern.
This patch checks the leading fixed part of a pathspec against base
directory and exit early if possible. We could even optimize further
in "path/to/something*.c" case (i.e. check the fixed part against
name_entry as well) but that's more complicated and probably does not
gain us much.
-O2 build on linux-2.6, without and with this patch respectively:
$ time git rev-list --quiet HEAD -- 'drivers/*.c'
real 1m9.484s
user 1m9.128s
sys 0m0.181s
$ time ~/w/git/git rev-list --quiet HEAD -- 'drivers/*.c'
real 0m15.710s
user 0m15.564s
sys 0m0.107s
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
tree-walk.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 62 insertions(+), 1 deletion(-)
diff --git a/tree-walk.c b/tree-walk.c
index 585899e..9d6e59b 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -573,6 +573,52 @@ static int match_dir_prefix(const char *base,
}
/*
+ * Perform matching on the leading non-wildcard part of
+ * pathspec. item->nowildcard_len must be greater than zero. Return
+ * non-zero if base is matched.
+ */
+static int match_wildcard_base(const struct pathspec_item *item,
+ const char *base, int baselen,
+ int *matched)
+{
+ const char *match = item->match;
+ /* the wildcard part is not considered in this function */
+ int matchlen = item->nowildcard_len;
+
+ if (baselen) {
+ int dirlen;
+ /*
+ * Return early if base is longer than the
+ * non-wildcard part but it does not match.
+ */
+ if (baselen >= matchlen) {
+ *matched = matchlen;
+ return !strncmp(base, match, matchlen);
+ }
+
+ dirlen = matchlen;
+ while (dirlen && match[dirlen - 1] != '/')
+ dirlen--;
+
+ /* Return early if base is shorter than the
+ non-wildcard part but it does not match. Note that
+ base ends with '/' so we are sure it really matches
+ directory */
+ if (strncmp(base, match, baselen))
+ return 0;
+ *matched = baselen;
+ } else
+ *matched = 0;
+ /*
+ * we could have checked entry against the non-wildcard part
+ * that is not in base and does similar never_interesting
+ * optimization as in match_entry. For now just be happy with
+ * base comparison.
+ */
+ return entry_interesting;
+}
+
+/*
* Is a tree entry interesting given the pathspec we have?
*
* Pre-condition: either baselen == base_offset (i.e. empty path)
@@ -602,7 +648,7 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
const struct pathspec_item *item = ps->items+i;
const char *match = item->match;
const char *base_str = base->buf + base_offset;
- int matchlen = item->len;
+ int matchlen = item->len, matched = 0;
if (baselen >= matchlen) {
/* If it doesn't match, move along... */
@@ -647,9 +693,24 @@ match_wildcards:
if (item->nowildcard_len == item->len)
continue;
+ if (item->nowildcard_len &&
+ !match_wildcard_base(item, base_str, baselen, &matched))
+ return entry_not_interesting;
+
/*
* Concatenate base and entry->path into one and do
* fnmatch() on it.
+ *
+ * While we could avoid concatenation in certain cases
+ * [1], which saves a memcpy and potentially a
+ * realloc, it turns out not worth it. Measurement on
+ * linux-2.6 does not show any clear improvements,
+ * partly because of the nowildcard_len optimization
+ * in git_fnmatch(). Avoid micro-optimizations here.
+ *
+ * [1] if match_wildcard_base() says the base
+ * directory is already matched, we only need to match
+ * the rest, which is shorter so _in theory_ faster.
*/
strbuf_add(base, entry->path, pathlen);
--
1.8.0.rc2.23.g1fb49df
^ permalink raw reply related
* [PATCH v2 3/4] pathspec: apply "*.c" optimization from exclude
From: Nguyễn Thái Ngọc Duy @ 2012-11-24 4:33 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1353731631-20593-1-git-send-email-pclouds@gmail.com>
When a pattern contains only a single asterisk as wildcard,
e.g. "foo*bar", after literally comparing the leading part "foo" with
the string, we can compare the tail of the string and make sure it
matches "bar", instead of running fnmatch() on "*bar" against the
remainder of the string.
-O2 build on linux-2.6, without the patch:
$ time git rev-list --quiet HEAD -- '*.c'
real 0m40.770s
user 0m40.290s
sys 0m0.256s
With the patch
$ time ~/w/git/git rev-list --quiet HEAD -- '*.c'
real 0m34.288s
user 0m33.997s
sys 0m0.205s
The above command is not supposed to be widely popular. It's chosen
because it exercises pathspec matching a lot. The point is it cuts
down matching time for popular patterns like *.c, which could be used
as pathspec in other places.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
The optimization's condition could be loosen to "only one asterisk"
(iow, fixed-length wildcards are OK, e.g. "abc[de]gh*.[ch]") when we
have a custom fnmatch implementation that supports dry-run, so it can
parse the pattern and determine the actual string length of
"abc[de]gh" and ".[ch]". We would have something similar to regcomp in
addition to git_fnmatch().
cache.h | 3 +++
dir.c | 18 ++++++++++++++++--
dir.h | 1 +
tree-walk.c | 6 ++++--
4 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/cache.h b/cache.h
index bf031f1..babf9e5 100644
--- a/cache.h
+++ b/cache.h
@@ -473,6 +473,8 @@ extern int index_name_is_other(const struct index_state *, const char *, int);
extern int ie_match_stat(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);
extern int ie_modified(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);
+#define PATHSPEC_ONESTAR 1 /* the pathspec pattern sastisfies GFNM_ONESTAR */
+
struct pathspec {
const char **raw; /* get_pathspec() result, not freed by free_pathspec() */
int nr;
@@ -483,6 +485,7 @@ struct pathspec {
const char *match;
int len;
int nowildcard_len;
+ int flags;
} *items;
};
diff --git a/dir.c b/dir.c
index f81e1d2..9afd388 100644
--- a/dir.c
+++ b/dir.c
@@ -46,6 +46,13 @@ inline int git_fnmatch(const char *pattern, const char *string,
pattern += prefix;
string += prefix;
}
+ if (flags & GFNM_ONESTAR) {
+ int pattern_len = strlen(++pattern);
+ int string_len = strlen(string);
+ return string_len < pattern_len ||
+ strcmp(pattern,
+ string + string_len - pattern_len);
+ }
return fnmatch(pattern, string, fnm_flags);
}
@@ -246,7 +253,9 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix,
}
if (item->nowildcard_len < item->len &&
- !git_fnmatch(match, name, 0, item->nowildcard_len - prefix))
+ !git_fnmatch(match, name,
+ item->flags & PATHSPEC_ONESTAR ? GFNM_ONESTAR : 0,
+ item->nowildcard_len - prefix))
return MATCHED_FNMATCH;
return 0;
@@ -1446,8 +1455,13 @@ int init_pathspec(struct pathspec *pathspec, const char **paths)
item->match = path;
item->len = strlen(path);
item->nowildcard_len = simple_length(path);
- if (item->nowildcard_len < item->len)
+ item->flags = 0;
+ if (item->nowildcard_len < item->len) {
pathspec->has_wildcard = 1;
+ if (path[item->nowildcard_len] == '*' &&
+ no_wildcard(path + item->nowildcard_len + 1))
+ item->flags |= PATHSPEC_ONESTAR;
+ }
}
qsort(pathspec->items, pathspec->nr,
diff --git a/dir.h b/dir.h
index 0e8ae84..ab5af42 100644
--- a/dir.h
+++ b/dir.h
@@ -143,6 +143,7 @@ extern int fnmatch_icase(const char *pattern, const char *string, int flags);
* The prefix part of pattern must not contains wildcards.
*/
#define GFNM_PATHNAME 1 /* similar to FNM_PATHNAME */
+#define GFNM_ONESTAR 2 /* there is only _one_ wildcard, a star */
extern int git_fnmatch(const char *pattern, const char *string,
int flags, int prefix);
diff --git a/tree-walk.c b/tree-walk.c
index 2fcf3c0..585899e 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -628,7 +628,8 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
if (item->nowildcard_len < item->len) {
if (!git_fnmatch(match + baselen, entry->path,
- 0, item->nowildcard_len - baselen))
+ item->flags & PATHSPEC_ONESTAR ? GFNM_ONESTAR : 0,
+ item->nowildcard_len - baselen))
return entry_interesting;
/*
@@ -654,7 +655,8 @@ match_wildcards:
strbuf_add(base, entry->path, pathlen);
if (!git_fnmatch(match, base->buf + base_offset,
- 0, item->nowildcard_len)) {
+ item->flags & PATHSPEC_ONESTAR ? GFNM_ONESTAR : 0,
+ item->nowildcard_len)) {
strbuf_setlen(base, base_offset + baselen);
return entry_interesting;
}
--
1.8.0.rc2.23.g1fb49df
^ permalink raw reply related
* [PATCH v2 1/4] pathspec: save the non-wildcard length part
From: Nguyễn Thái Ngọc Duy @ 2012-11-24 4:33 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1353731631-20593-1-git-send-email-pclouds@gmail.com>
We mark pathspec with wildcards with the field use_wildcard. We
could do better by saving the length of the non-wildcard part, which
can be used for optimizations such as f9f6e2c (exclude: do strcmp as
much as possible before fnmatch - 2012-06-07).
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
builtin/ls-files.c | 2 +-
builtin/ls-tree.c | 2 +-
cache.h | 2 +-
dir.c | 6 +++---
tree-walk.c | 4 ++--
5 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index b5434af..4a9ee69 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -337,7 +337,7 @@ void overlay_tree_on_cache(const char *tree_name, const char *prefix)
matchbuf[0] = prefix;
matchbuf[1] = NULL;
init_pathspec(&pathspec, matchbuf);
- pathspec.items[0].use_wildcard = 0;
+ pathspec.items[0].nowildcard_len = pathspec.items[0].len;
} else
init_pathspec(&pathspec, NULL);
if (read_tree(tree, 1, &pathspec))
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index 235c17c..fb76e38 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -168,7 +168,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
init_pathspec(&pathspec, get_pathspec(prefix, argv + 1));
for (i = 0; i < pathspec.nr; i++)
- pathspec.items[i].use_wildcard = 0;
+ pathspec.items[i].nowildcard_len = pathspec.items[i].len;
pathspec.has_wildcard = 0;
tree = parse_tree_indirect(sha1);
if (!tree)
diff --git a/cache.h b/cache.h
index dbd8018..bf031f1 100644
--- a/cache.h
+++ b/cache.h
@@ -482,7 +482,7 @@ struct pathspec {
struct pathspec_item {
const char *match;
int len;
- unsigned int use_wildcard:1;
+ int nowildcard_len;
} *items;
};
diff --git a/dir.c b/dir.c
index 5a83aa7..c391d46 100644
--- a/dir.c
+++ b/dir.c
@@ -230,7 +230,7 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix,
return MATCHED_RECURSIVELY;
}
- if (item->use_wildcard && !fnmatch(match, name, 0))
+ if (item->nowildcard_len < item->len && !fnmatch(match, name, 0))
return MATCHED_FNMATCH;
return 0;
@@ -1429,8 +1429,8 @@ int init_pathspec(struct pathspec *pathspec, const char **paths)
item->match = path;
item->len = strlen(path);
- item->use_wildcard = !no_wildcard(path);
- if (item->use_wildcard)
+ item->nowildcard_len = simple_length(path);
+ if (item->nowildcard_len < item->len)
pathspec->has_wildcard = 1;
}
diff --git a/tree-walk.c b/tree-walk.c
index 3f54c02..af871c5 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -626,7 +626,7 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
&never_interesting))
return entry_interesting;
- if (item->use_wildcard) {
+ if (item->nowildcard_len < item->len) {
if (!fnmatch(match + baselen, entry->path, 0))
return entry_interesting;
@@ -642,7 +642,7 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
}
match_wildcards:
- if (!item->use_wildcard)
+ if (item->nowildcard_len == item->len)
continue;
/*
--
1.8.0.rc2.23.g1fb49df
^ permalink raw reply related
* [PATCH v2 2/4] pathspec: do exact comparison on the leading non-wildcard part
From: Nguyễn Thái Ngọc Duy @ 2012-11-24 4:33 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1353731631-20593-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
dir.c | 18 +++++++++++++++++-
dir.h | 8 ++++++++
tree-walk.c | 6 ++++--
3 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/dir.c b/dir.c
index c391d46..f81e1d2 100644
--- a/dir.c
+++ b/dir.c
@@ -34,6 +34,21 @@ int fnmatch_icase(const char *pattern, const char *string, int flags)
return fnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD : 0));
}
+inline int git_fnmatch(const char *pattern, const char *string,
+ int flags, int prefix)
+{
+ int fnm_flags = 0;
+ if (flags & GFNM_PATHNAME)
+ fnm_flags |= FNM_PATHNAME;
+ if (prefix > 0) {
+ if (strncmp(pattern, string, prefix))
+ return FNM_NOMATCH;
+ pattern += prefix;
+ string += prefix;
+ }
+ return fnmatch(pattern, string, fnm_flags);
+}
+
static size_t common_prefix_len(const char **pathspec)
{
const char *n, *first;
@@ -230,7 +245,8 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix,
return MATCHED_RECURSIVELY;
}
- if (item->nowildcard_len < item->len && !fnmatch(match, name, 0))
+ if (item->nowildcard_len < item->len &&
+ !git_fnmatch(match, name, 0, item->nowildcard_len - prefix))
return MATCHED_FNMATCH;
return 0;
diff --git a/dir.h b/dir.h
index f5c89e3..0e8ae84 100644
--- a/dir.h
+++ b/dir.h
@@ -139,4 +139,12 @@ extern int strcmp_icase(const char *a, const char *b);
extern int strncmp_icase(const char *a, const char *b, size_t count);
extern int fnmatch_icase(const char *pattern, const char *string, int flags);
+/*
+ * The prefix part of pattern must not contains wildcards.
+ */
+#define GFNM_PATHNAME 1 /* similar to FNM_PATHNAME */
+
+extern int git_fnmatch(const char *pattern, const char *string,
+ int flags, int prefix);
+
#endif
diff --git a/tree-walk.c b/tree-walk.c
index af871c5..2fcf3c0 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -627,7 +627,8 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
return entry_interesting;
if (item->nowildcard_len < item->len) {
- if (!fnmatch(match + baselen, entry->path, 0))
+ if (!git_fnmatch(match + baselen, entry->path,
+ 0, item->nowildcard_len - baselen))
return entry_interesting;
/*
@@ -652,7 +653,8 @@ match_wildcards:
strbuf_add(base, entry->path, pathlen);
- if (!fnmatch(match, base->buf + base_offset, 0)) {
+ if (!git_fnmatch(match, base->buf + base_offset,
+ 0, item->nowildcard_len)) {
strbuf_setlen(base, base_offset + baselen);
return entry_interesting;
}
--
1.8.0.rc2.23.g1fb49df
^ permalink raw reply related
* [PATCH v2 0/4] nd/pathspec-wildcard
From: Nguyễn Thái Ngọc Duy @ 2012-11-24 4:33 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
The only change (apart from what Junio's made after I sent the series)
is rename GF_* to GFNM_* and PSF_* to PATHSPEC_* with a brief explanation
for each flag.
.gitignore code does not have "foo*oob" bug that the original series has.
Nguyễn Thái Ngọc Duy (4):
pathspec: save the non-wildcard length part
pathspec: do exact comparison on the leading non-wildcard part
pathspec: apply "*.c" optimization from exclude
tree_entry_interesting: do basedir compare on wildcard patterns when
possible
builtin/ls-files.c | 2 +-
builtin/ls-tree.c | 2 +-
cache.h | 5 +++-
dir.c | 36 +++++++++++++++++++++++---
dir.h | 9 +++++++
tree-walk.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++----
6 files changed, 118 insertions(+), 11 deletions(-)
--
1.8.0.rc2.23.g1fb49df
^ permalink raw reply
* Re: [PATCH v6 p2 1/9] transport-helper: update remote helper namespace
From: Felipe Contreras @ 2012-11-24 3:28 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Jeff King, Ilari Liusvaara, Sverre Rabbelier,
Felipe Contreras, Elijah Newren, Thiago Farina
In-Reply-To: <1353727520-26039-2-git-send-email-felipe.contreras@gmail.com>
On Sat, Nov 24, 2012 at 4:25 AM, Felipe Contreras
<felipe.contreras@gmail.com> wrote:
> @@ -673,11 +675,23 @@ static void push_update_refs_status(struct helper_data *data,
> struct strbuf buf = STRBUF_INIT;
> struct ref *ref = remote_refs;
> for (;;) {
> + char *private;
> +
> recvline(data, &buf);
> if (!buf.len)
> break;
>
> - push_update_ref_status(&buf, &ref, remote_refs);
> + if (push_update_ref_status(&buf, &ref, remote_refs))
> + continue;
> +
> + if (!data->refspecs)
> + continue;
> +
> + /* propagate back the update to the remote namespace */
> + private = apply_refspecs(data->refspecs, data->refspec_nr, ref->name);
> + if (!private)
> + continue;
> + update_ref("update by helper", private, ref->new_sha1, NULL, 0, 0);
free(private); I guess
--
Felipe Contreras
^ permalink raw reply
* Re: [PATCH v6 p2 2/9] fast-export: don't handle uninteresting refs
From: Felipe Contreras @ 2012-11-24 3:27 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Jeff King, Ilari Liusvaara, Sverre Rabbelier,
Felipe Contreras, Elijah Newren, Thiago Farina
In-Reply-To: <1353727520-26039-3-git-send-email-felipe.contreras@gmail.com>
On Sat, Nov 24, 2012 at 4:25 AM, Felipe Contreras
<felipe.contreras@gmail.com> wrote:
> +cat > expected << EOF
> +blob
> +mark :13
> +data 5
> +bump
> +
> +commit refs/heads/master
> +mark :14
> +author A U Thor <author@example.com> 1112912773 -0700
> +committer C O Mitter <committer@example.com> 1112912773 -0700
> +data 5
> +bump
> +from :12
> +M 100644 :13 file
> +
> +EOF
> +
> +test_expect_success 'refs are updated even if no commits need to be exported' '
The title should be updated: 'avoid uninteresting refs'
--
Felipe Contreras
^ permalink raw reply
* [PATCH v6 p2 9/9] fast-export: trivial cleanups
From: Felipe Contreras @ 2012-11-24 3:25 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Jeff King, Ilari Liusvaara, Sverre Rabbelier,
Felipe Contreras, Elijah Newren, Thiago Farina
In-Reply-To: <1353727520-26039-1-git-send-email-felipe.contreras@gmail.com>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
builtin/fast-export.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index d88fa10..bf5c822 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -548,7 +548,6 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info)
static void handle_tags_and_duplicates(void)
{
- struct commit *commit;
int i;
for (i = extra_refs.nr - 1; i >= 0; i--) {
@@ -560,9 +559,7 @@ static void handle_tags_and_duplicates(void)
break;
case OBJ_COMMIT:
/* create refs pointing to already seen commits */
- commit = (struct commit *)object;
- printf("reset %s\nfrom :%d\n\n", name,
- get_object_mark(&commit->object));
+ printf("reset %s\nfrom :%d\n\n", name, get_object_mark(object));
show_progress();
break;
}
--
1.8.0
^ permalink raw reply related
* [PATCH v6 p2 8/9] fast-export: refactor get_tags_and_duplicates()
From: Felipe Contreras @ 2012-11-24 3:25 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Jeff King, Ilari Liusvaara, Sverre Rabbelier,
Felipe Contreras, Elijah Newren, Thiago Farina
In-Reply-To: <1353727520-26039-1-git-send-email-felipe.contreras@gmail.com>
Split into a separate helper function get_commit() so that the part that
finds the relevant commit, and the part that does something with it
(handle tag object, etc.) are in different places.
No functional changes.
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
builtin/fast-export.c | 68 ++++++++++++++++++++++++++++-----------------------
1 file changed, 38 insertions(+), 30 deletions(-)
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 5035382..d88fa10 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -475,9 +475,32 @@ static void handle_tag(const char *name, struct tag *tag)
(int)message_size, (int)message_size, message ? message : "");
}
+static struct commit *get_commit(struct rev_cmdline_entry *e, char *full_name)
+{
+ switch (e->item->type) {
+ case OBJ_COMMIT:
+ return (struct commit *)e->item;
+ case OBJ_TAG: {
+ struct tag *tag = (struct tag *)e->item;
+
+ /* handle nested tags */
+ while (tag && tag->object.type == OBJ_TAG) {
+ parse_object(tag->object.sha1);
+ string_list_append(&extra_refs, full_name)->util = tag;
+ tag = (struct tag *)tag->tagged;
+ }
+ if (!tag)
+ die("Tag %s points nowhere?", e->name);
+ return (struct commit *)tag;
+ break;
+ }
+ default:
+ return NULL;
+ }
+}
+
static void get_tags_and_duplicates(struct rev_cmdline_info *info)
{
- struct tag *tag;
int i;
for (i = 0; i < info->nr; i++) {
@@ -492,41 +515,26 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info)
if (dwim_ref(e->name, strlen(e->name), sha1, &full_name) != 1)
continue;
- switch (e->item->type) {
- case OBJ_COMMIT:
- commit = (struct commit *)e->item;
- break;
- case OBJ_TAG:
- tag = (struct tag *)e->item;
-
- /* handle nested tags */
- while (tag && tag->object.type == OBJ_TAG) {
- parse_object(tag->object.sha1);
- string_list_append(&extra_refs, full_name)->util = tag;
- tag = (struct tag *)tag->tagged;
- }
- if (!tag)
- die ("Tag %s points nowhere?", e->name);
- switch(tag->object.type) {
- case OBJ_COMMIT:
- commit = (struct commit *)tag;
- break;
- case OBJ_BLOB:
- handle_object(tag->object.sha1);
- continue;
- default: /* OBJ_TAG (nested tags) is already handled */
- warning("Tag points to object of unexpected type %s, skipping.",
- typename(tag->object.type));
- continue;
- }
- break;
- default:
+ commit = get_commit(e, full_name);
+ if (!commit) {
warning("%s: Unexpected object of type %s, skipping.",
e->name,
typename(e->item->type));
continue;
}
+ switch(commit->object.type) {
+ case OBJ_COMMIT:
+ break;
+ case OBJ_BLOB:
+ handle_object(commit->object.sha1);
+ continue;
+ default: /* OBJ_TAG (nested tags) is already handled */
+ warning("Tag points to object of unexpected type %s, skipping.",
+ typename(commit->object.type));
+ continue;
+ }
+
/*
* This ref will not be updated through a commit, lets make
* sure it gets properly updated eventually.
--
1.8.0
^ permalink raw reply related
* [PATCH v6 p2 6/9] transport-helper: fix push without marks
From: Felipe Contreras @ 2012-11-24 3:25 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Jeff King, Ilari Liusvaara, Sverre Rabbelier,
Felipe Contreras, Elijah Newren, Thiago Farina
In-Reply-To: <1353727520-26039-1-git-send-email-felipe.contreras@gmail.com>
There's not much to do when marks are not available, except pushing
everything, so let's do so by avoiding the negative refs (e.g.
^refs/testgit/origin/master).
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
t/t5801-remote-helpers.sh | 2 +-
transport-helper.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh
index 9c7871b..456303b 100755
--- a/t/t5801-remote-helpers.sh
+++ b/t/t5801-remote-helpers.sh
@@ -141,7 +141,7 @@ test_expect_success 'pulling without marks' '
compare_refs local2 HEAD server HEAD
'
-test_expect_failure 'pushing without marks' '
+test_expect_success 'pushing without marks' '
test_when_finished "(cd local2 && git reset --hard origin)" &&
(cd local2 &&
echo content >>file &&
diff --git a/transport-helper.c b/transport-helper.c
index 6dbb72e..78e4e82 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -781,7 +781,7 @@ static int push_refs_with_export(struct transport *transport,
if (ref->peer_ref)
string_list_append(&revlist_args, ref->peer_ref->name);
- if (!data->refspecs)
+ if (!data->refspecs || !data->import_marks)
continue;
private = apply_refspecs(data->refspecs, data->refspec_nr, ref->name);
if (private && strcmp(private, ref->name) && !get_sha1(private, sha1)) {
--
1.8.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox