* AW: Moving commits from one branch to another
From: Schulze, Stefan @ 2013-01-23 15:44 UTC (permalink / raw)
To: git@vger.kernel.org
In-Reply-To: <20130123144941.GO7498@serenity.lan>
> git rebase --onto svnbranch publishedToSvn master^0
> git checkout -B svnbranch HEAD
Great! This does exactly what I want!
Thanks for your support,
Stefan Schulze
--------------------------
ckc ag
Sitz:
Am Alten Bahnhof 13
38122 Braunschweig
Telefon +49 (0)531 / 80 110 0
Telefax +49 (0)531 / 80 110 18444
http://www.ckc-group.de
Amtsgericht Braunschweig
HRB 5405
Vorstand:
H.-G. Christian Krentel
(Vorsitzender)
Karsten Kisser
Aufsichtsrat:
Dr. Heinz-Werner Weinrich
(Vorsitzender)
Jens Fokuhl
(stellv. Vorsitzender)
Prof. Dr. Reinhold Haux
Cäsar Jaworski
Dr. Rita Schulz
Thorsten Sponholz
--------------------------
^ permalink raw reply
* Re: GIT get corrupted on lustre
From: Thomas Rast @ 2013-01-23 15:44 UTC (permalink / raw)
To: kusmabite
Cc: Thomas Rast, Eric Chamberland, Brian J. Murrell, git,
Pyeron, Jason J CTR (US), Maxime Boissonneault, Philippe Vaucher,
Sébastien Boisvert
In-Reply-To: <CABPQNSb89h28O_a3uVoVrNisZqPcHHVFm8nP7GdFGCb=PVdcsQ@mail.gmail.com>
Erik Faye-Lund <kusmabite@gmail.com> writes:
> On Wed, Jan 23, 2013 at 4:32 PM, Thomas Rast <trast@student.ethz.ch> wrote:
>> Erik Faye-Lund <kusmabite@gmail.com> writes:
>>
>>> POSIX allows error codes
>>> to be generated other than those defined. From
>>> http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_03.html:
>>>
>>> "Implementations may support additional errors not included in this
>>> list, *may generate errors included in this list under circumstances
>>> other than those described here*, or may contain extensions or
>>> limitations that prevent some errors from occurring."
>>
>> That same page says, however:
>>
>> For functions under the Threads option for which [EINTR] is not listed
>> as a possible error condition in this volume of IEEE Std 1003.1-2001,
>> an implementation shall not return an error code of [EINTR].
>
> Yes, but surely that's for pthreads functions, no? utime is not one of
> those functions...
Ah, my bad. In fact in
http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xsh_chap02.html
there is a paragraph "Signal Effects on Other Functions", which says
The most common behavior of an interrupted function after a
signal-catching function returns is for the interrupted function to
give an [EINTR] error unless the SA_RESTART flag is in effect for the
signal. However, there are a number of specific exceptions, including
sleep() and certain situations with read() and write().
The historical implementations of many functions defined by IEEE Std
1003.1-2001 are not interruptible[...]
Functions not mentioned explicitly as interruptible may be so on some
implementations, possibly as an extension where the function gives an
[EINTR] error. There are several functions (for example, getpid(),
getuid()) that are specified as never returning an error, which can
thus never be extended in this way.
If a signal-catching function returns while the SA_RESTART flag is in
effect, an interrupted function is restarted at the point it was
interrupted. Conforming applications cannot make assumptions about the
internal behavior of interrupted functions, even if the functions are
async-signal-safe. For example, suppose the read() function is
interrupted with SA_RESTART in effect, the signal-catching function
closes the file descriptor being read from and returns, and the read()
function is then restarted; in this case the application cannot assume
that the read() function will give an [EBADF] error, since read()
might have checked the file descriptor for validity before being
interrupted.
Taken together this should mean that the bug is in fact simply that the
calls do not *restart*. They are (like you say) allowed to return EINTR
despite not being specified to, *but* SA_RESTART should restart it.
Now, does that make it a lustre bug or a glibc bug? :-)
--
Thomas Rast
trast@{inf,student}.ethz.ch
^ permalink raw reply
* Re: GIT get corrupted on lustre
From: Erik Faye-Lund @ 2013-01-23 15:54 UTC (permalink / raw)
To: Thomas Rast
Cc: Thomas Rast, Eric Chamberland, Brian J. Murrell, git,
Pyeron, Jason J CTR (US), Maxime Boissonneault, Philippe Vaucher,
Sébastien Boisvert
In-Reply-To: <871udbc3af.fsf@pctrast.inf.ethz.ch>
On Wed, Jan 23, 2013 at 4:44 PM, Thomas Rast <trast@inf.ethz.ch> wrote:
> Erik Faye-Lund <kusmabite@gmail.com> writes:
>
>> On Wed, Jan 23, 2013 at 4:32 PM, Thomas Rast <trast@student.ethz.ch> wrote:
>>> Erik Faye-Lund <kusmabite@gmail.com> writes:
>>>
>>>> POSIX allows error codes
>>>> to be generated other than those defined. From
>>>> http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_03.html:
>>>>
>>>> "Implementations may support additional errors not included in this
>>>> list, *may generate errors included in this list under circumstances
>>>> other than those described here*, or may contain extensions or
>>>> limitations that prevent some errors from occurring."
>>>
>>> That same page says, however:
>>>
>>> For functions under the Threads option for which [EINTR] is not listed
>>> as a possible error condition in this volume of IEEE Std 1003.1-2001,
>>> an implementation shall not return an error code of [EINTR].
>>
>> Yes, but surely that's for pthreads functions, no? utime is not one of
>> those functions...
>
> Ah, my bad. In fact in
>
> http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xsh_chap02.html
>
> there is a paragraph "Signal Effects on Other Functions", which says
>
> <snip>
>
> Taken together this should mean that the bug is in fact simply that the
> calls do not *restart*. They are (like you say) allowed to return EINTR
> despite not being specified to, *but* SA_RESTART should restart it.
>
Right, thanks for clearing that up.
> Now, does that make it a lustre bug or a glibc bug? :-)
That's kind of uninteresting, the important bit is that it is indeed a
bug (outside of Git).
^ permalink raw reply
* Re: [PATCH v2 2/3] push: introduce REJECT_FETCH_FIRST and REJECT_NEEDS_FORCE
From: Junio C Hamano @ 2013-01-23 16:28 UTC (permalink / raw)
To: Jeff King; +Cc: git, Chris Rorvick
In-Reply-To: <20130123065640.GB10306@sigill.intra.peff.net>
Jeff King <peff@peff.net> writes:
> On Mon, Jan 21, 2013 at 10:30:29PM -0800, Junio C Hamano wrote:
>
>> When we push to update an existing ref, if:
>>
>> * we do not have the object at the tip of the remote; or
>> * the object at the tip of the remote is not a commit; or
>> * the object we are pushing is not a commit,
>>
>> there is no point suggesting to fetch, integrate and push again.
>>
>> If we do not have the current object at the tip of the remote, we
>> should tell the user to fetch first and evaluate the situation
>> before deciding what to do next.
>
> Should we? I know that it is more correct to do so, because we do not
> even know for sure that the remote object is a commit, and fetching
> _might_ lead to us saying "hey, this is not something that can be
> fast-forwarded".
>
> But by far the common case will be that it _is_ a commit, and the right
> thing is going to be to pull....
> Is the extra hassle in the common case worth it for the off chance that
> we might give a more accurate message? Should the "fetch first" message
> be some hybrid that covers both cases accurately, but still points the
> user towards "git pull" (which will fail anyway if the remote ref is not
> a commit)?
I was actually much less happy with "needs force" than this one, as
you have to assume too many things for the message to be a useful
and a safe advise: the user has actually examined the situation and
forcing the push is the right thing to do. Both old and new objects
exist, so the user _could_ have done so, but did he really check
them, thought about the situation and made the right decision?
Perhaps the attempted push had a typo in the object name it wanted
to update the other end with, and the right thing to do is not to
force but to fix the refspec instead? "You need --force to perform
this push" was a very counter-productive advice in this case, but I
didn't think of a better wording.
The "fetch first and inspect" was an attempt to reduce the risk of
that "needs force" message that could encourage brainless forced
pushes. Perhaps if we reword "needs force" to something less risky,
we do not have to be so explicit in "You have to fetch first and
examine".
How about doing this?
For "needs force" cases, we say this instead:
hint: you cannot update a ref that points at a non-commit object, or
hint: update a ref to point at a non-commit object, without --force.
Being explicit about "non-commit" twice will catch user's eyes and
cause him to double check that it is not a mistyped LHS of the push
refspec (if he is sending a non-commit) or mistyped RHS (if the ref
is pointing at a non-commit). If he _is_ trying to push a blob out,
the advice makes it clear what to do next: he does want to force it.
If we did that, then we could loosen the "You should fetch first"
case to say something like this:
hint: you do not have the object at the tip of the remote ref;
hint: perhaps you want to pull from there first?
This explicitly denies one of Chris's wish "we shouldn't suggest to
merge something that we may not be able to", but in the "You should
fetch first" case, we cannot fundamentally know if we can merge
until we fetch. I agree with you that the most common case is that
the unknown object is a commit, and that suggesting to pull is a
good compromise.
Note that you _could_ split the "needs force" case into two, namely,
"cannot replace a non-commit" and "cannot push a non-commit". You
could even further split them into combinations (e.g. an attempt to
replace an annotated tag with a commit and an attempt to replace a
tree with a commit may be different situations), but I think the
advices we can give to these cases would end up being the same, so I
tend to think it is not worth it. That is what I meant by "I do not
expect me doing the type-based policy myself" in the concluding
message of the series.
^ permalink raw reply
* Re: Bug in latest gitk - can't click lines connecting commits
From: Junio C Hamano @ 2013-01-23 16:35 UTC (permalink / raw)
To: Paul Mackerras; +Cc: git
In-Reply-To: <20130123114806.GA21124@iris.ozlabs.ibm.com>
Paul Mackerras <paulus@samba.org> writes:
> On Tue, Jan 22, 2013 at 09:28:23AM -0800, Junio C Hamano wrote:
>>
>> I notice that I have a handful of commits that I haven't pulled from
>> your repository, and the last commit on your 'master' is about 20
>> days old. Is it safe for me to pull these now?
>
> Yes, please pull them now.
Thanks.
^ permalink raw reply
* Re: [PATCH v2] all: new command used for multi-repo operations
From: Junio C Hamano @ 2013-01-23 16:52 UTC (permalink / raw)
To: Lars Hjemli; +Cc: git
In-Reply-To: <1358928767-16283-1-git-send-email-hjemli@gmail.com>
Lars Hjemli <hjemli@gmail.com> writes:
> +static int walk(struct strbuf *path, int argc, const char **argv)
> +{
> + DIR *dir;
> + struct dirent *ent;
> + struct stat st;
> + size_t len;
> +
> + dir = opendir(path->buf);
> + if (!dir)
> + return errno;
> + strbuf_addstr(path, "/");
> + len = path->len;
> + while ((ent = readdir(dir))) {
> + if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
> + continue;
> + if (!strcmp(ent->d_name, ".git")) {
> + strbuf_addstr(path, ent->d_name);
> + setenv(GIT_DIR_ENVIRONMENT, path->buf, 1);
> + strbuf_setlen(path, len - 1);
> + setenv(GIT_WORK_TREE_ENVIRONMENT, path->buf, 1);
> + handle_repo(path->buf, argv);
> + strbuf_addstr(path, "/");
> + continue;
> + }
> + strbuf_setlen(path, len);
> + strbuf_addstr(path, ent->d_name);
> + switch (DTYPE(ent)) {
> + case DT_UNKNOWN:
> + /* Use stat() instead of lstat(), since we want to
> + * know if we can follow this path into another
> + * directory - it's not important if it's actually
> + * a symlink which gets us there.
> + */
This is wrong if you are on a platform that does have d_type, no?
It may say it is a symbolic link, and until you stat you wouldn't
know if it may lead to a directory. You can add "case DT_LNK:" that
behaves the same as DT_UNKNOWN, I think.
> + if (stat(path->buf, &st) || !S_ISDIR(st.st_mode))
> + break;
> + /* fallthrough */
> + case DT_DIR:
> + walk(path, argc, argv);
> + break;
> + }
> + strbuf_setlen(path, len);
> + }
But I still do not think this loop is correct. In a repository that
has a working tree, you would learn that directory $D has $D/.git in
it, feed $D to handle_repo(), and then descend into $D/.git/objects/,
$D/.git/refs, and other random directories to see if you can find
other repositories. That is just not right.
If this check were doing something like "The directory $D is worth
handing to handle_repo() if it has all of the following: objects/,
refs/ and HEAD that either points inside refs/ or 40-hex.", then it
would make a lot more sense to me, including the part that goes on
to check sibling directories. As a bonus side effect, it will give
you a support for bare repositories for free.
^ permalink raw reply
* Re: [PATCH/RFC] Revoke write access to refs and odb after importing another repo's odb
From: Junio C Hamano @ 2013-01-23 17:01 UTC (permalink / raw)
To: Nguyễn Thái Ngọc Duy; +Cc: git, Jens Lehmann
In-Reply-To: <1358948067-2792-1-git-send-email-pclouds@gmail.com>
Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:
> add_submodule_odb() can be used to import objects from another
> repository temporarily. After this point we don't know which objects
> are ours, which are external. If we create an object that refers to an
> external object, next time git runs, it may find a hole in the object
> graph because the external repository may not be imported. The same
> goes for pointing a ref to an external SHA-1.
>
> To protect ourselves, once add_submodule_odb() is used:
>
> - trees, tags and commits cannot be created
> - refs cannot be updated
>
> In certain cases that submodule code knows that it's safe to write, it
> can turn the readonly flag off.
>
> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
> ---
> I think this is a good safety check.
Two step implementation to bring "read-only" support into a testable
shape and then flip that bit in add_submdule_odb() would be a
sensible approach.
I however have this suspicion that this will become a losing battle
and we would be better off getting rid of add_submodule_odb();
instead operations that work across repositories will be done as a
subprocess, which will get us back closer to one of the original
design goals of submodule support to have a clear separation between
the superproject and its submodules.
^ permalink raw reply
* Re: [PATCH v2] all: new command used for multi-repo operations
From: Junio C Hamano @ 2013-01-23 17:04 UTC (permalink / raw)
To: Lars Hjemli; +Cc: git
In-Reply-To: <7v622nj0ys.fsf@alter.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> writes:
> But I still do not think this loop is correct. In a repository that
> has a working tree, you would learn that directory $D has $D/.git in
> it, feed $D to handle_repo(), and then descend into $D/.git/objects/,
> $D/.git/refs, and other random directories to see if you can find
> other repositories....
Ahh, no, you don't.
I still think calling is_git_directory() on $D + "/.git" would be a
better implementation, though.
^ permalink raw reply
* Re: What's cooking in git.git (Jan 2013, #08; Tue, 22)
From: Junio C Hamano @ 2013-01-23 17:13 UTC (permalink / raw)
To: John Keeping; +Cc: git, Eric S. Raymond, Chris Rorvick
In-Reply-To: <20130123092858.GJ7498@serenity.lan>
John Keeping <john@keeping.me.uk> writes:
> My preference would be for something like this, possibly with an
> expanded examples section showing how to pipe the output of cvsps-3 or
> cvs2git into git-fast-import:
>
> -- >8 --
>
> diff --git a/Documentation/git-cvsimport.txt b/Documentation/git-cvsimport.txt
> index 9d5353e..20b846e 100644
> --- a/Documentation/git-cvsimport.txt
> +++ b/Documentation/git-cvsimport.txt
> @@ -18,6 +18,11 @@ SYNOPSIS
>
> DESCRIPTION
> -----------
> +*WARNING:* `git cvsimport` uses cvsps version 2, which is considered
> +deprecated; it does not work with cvsps version 3 and later. If you are
> +performing a one-shot import of a CVS repository consider using cvsps-3,
> +cvs2git or parsecvs directly.
> +
> Imports a CVS repository into git. It will either create a new
> repository, or incrementally import into an existing one.
>
> -- 8< --
OK, that is certainly a lot simpler to explain.
Is it "it does not work yet with cvsps3", or "it will not ever work
with cvsps3"? The impression I am getting is that it is the latter.
Also, should we have a suggestion to people who are *not* performing
a one-shot import, i.e. doing incremental or bidirectional?
^ permalink raw reply
* Re: GIT get corrupted on lustre
From: Jonathan Nieder @ 2013-01-23 17:23 UTC (permalink / raw)
To: Thomas Rast
Cc: kusmabite, Thomas Rast, Eric Chamberland, Brian J. Murrell, git,
Pyeron, Jason J CTR (US), Maxime Boissonneault, Philippe Vaucher,
Sébastien Boisvert
In-Reply-To: <871udbc3af.fsf@pctrast.inf.ethz.ch>
Thomas Rast wrote:
> Taken together this should mean that the bug is in fact simply that the
> calls do not *restart*. They are (like you say) allowed to return EINTR
> despite not being specified to, *but* SA_RESTART should restart it.
>
> Now, does that make it a lustre bug or a glibc bug? :-)
The kernel takes care of SA_RESTART, if I remember correctly. (See
arch/x86/kernel/signal.c::handle_signal() case -ERESTARTSYS.)
^ permalink raw reply
* Defensive publication on Git replication
From: Don Marti @ 2013-01-23 18:00 UTC (permalink / raw)
To: git
In-Reply-To: <a3951c54-efb8-476f-952f-4893bcc5e4a9@caret.perforce.com>
Just wanted to get this simple scheme out there in the hope of minimizing
patent troll risks for people working on replication.
You run an update hook that blocks pushes unless the branch reference in
the repository matches the corresponding reference stored in a synchronized
system, and flood the objects out using an inexpensive, simple system.
(Apologies if this is too obvious for the list; I didn't want to take
chances with the patent office definition of "obvious.")
Replication Mechanism for a Distributed Version Control System
http://ip.com/IPCOM/000225058
Disclosed is a mechanism for replication of content repositories of a
distributed version control system (DVCS), which is unique in that objects
and branch references are transferred between nodes by independent means,
with only branch references subject to synchronization among nodes. The
object of this disclosure is to simplify deployment of a DVCS in a
replicated configuration. Replication can be performed efficiently by
transferring objects using a key-value store, such as a distributed hash
table (DHT), independently of a repository's branch references, which are
transferred using a synchronized data store.
--
Don Marti Perforce Software +1-510-473-3142
http://www.perforce.com/git-fusion
^ permalink raw reply
* Re: [PATCH v2] all: new command used for multi-repo operations
From: Lars Hjemli @ 2013-01-23 18:19 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7v622nj0ys.fsf@alter.siamese.dyndns.org>
On Wed, Jan 23, 2013 at 5:52 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Lars Hjemli <hjemli@gmail.com> writes:
>
>> +static int walk(struct strbuf *path, int argc, const char **argv)
>> +{
>> + DIR *dir;
>> + struct dirent *ent;
>> + struct stat st;
>> + size_t len;
>> +
>> + dir = opendir(path->buf);
>> + if (!dir)
>> + return errno;
>> + strbuf_addstr(path, "/");
>> + len = path->len;
>> + while ((ent = readdir(dir))) {
>> + if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
>> + continue;
>> + if (!strcmp(ent->d_name, ".git")) {
>> + strbuf_addstr(path, ent->d_name);
>> + setenv(GIT_DIR_ENVIRONMENT, path->buf, 1);
>> + strbuf_setlen(path, len - 1);
>> + setenv(GIT_WORK_TREE_ENVIRONMENT, path->buf, 1);
>> + handle_repo(path->buf, argv);
>> + strbuf_addstr(path, "/");
>> + continue;
>> + }
>> + strbuf_setlen(path, len);
>> + strbuf_addstr(path, ent->d_name);
>> + switch (DTYPE(ent)) {
>> + case DT_UNKNOWN:
>> + /* Use stat() instead of lstat(), since we want to
>> + * know if we can follow this path into another
>> + * directory - it's not important if it's actually
>> + * a symlink which gets us there.
>> + */
>
> This is wrong if you are on a platform that does have d_type, no?
> It may say it is a symbolic link, and until you stat you wouldn't
> know if it may lead to a directory. You can add "case DT_LNK:" that
> behaves the same as DT_UNKNOWN, I think.
Yeah, that seems right, thanks.
--
larsh
^ permalink raw reply
* Re: [PATCH v2] all: new command used for multi-repo operations
From: Lars Hjemli @ 2013-01-23 18:29 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vwqv3hlu7.fsf@alter.siamese.dyndns.org>
On Wed, Jan 23, 2013 at 6:04 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Junio C Hamano <gitster@pobox.com> writes:
>
>> But I still do not think this loop is correct. In a repository that
>> has a working tree, you would learn that directory $D has $D/.git in
>> it, feed $D to handle_repo(), and then descend into $D/.git/objects/,
>> $D/.git/refs, and other random directories to see if you can find
>> other repositories....
>
> Ahh, no, you don't.
>
> I still think calling is_git_directory() on $D + "/.git" would be a
> better implementation, though.
Except for the .gitfile case, which is_git_directory() doesn't seem to
handle. I guess I can invoke read_gitfile() when i see that .git is a
file.
--
larsh
^ permalink raw reply
* Re: GIT get corrupted on lustre
From: Sébastien Boisvert @ 2013-01-23 18:34 UTC (permalink / raw)
To: Thomas Rast
Cc: Eric Chamberland, Brian J. Murrell, git, kusmabite,
Pyeron, Jason J CTR (US), Maxime Boissonneault, Philippe Vaucher
In-Reply-To: <878v7keuh3.fsf@pctrast.inf.ethz.ch>
[-- Attachment #1: Type: text/plain, Size: 1198 bytes --]
Hello,
Here is a patch (with git format-patch) that removes any timer if NO_SETITIMER is set.
Éric:
To test it with your workflow:
$ module load apps/git/1.8.1.1.348.g78eb407-NO_SETITIMER-patch
$ git clone ...
Sébastien
On 01/22/2013 05:14 PM, Thomas Rast wrote:
> Eric Chamberland <Eric.Chamberland@giref.ulaval.ca> writes:
>
>> So, hum, do we have some sort of conclusion?
>>
>> Shall it be a fix for git to get around that lustre "behavior"?
>>
>> If something can be done in git it would be great: it is a *lot*
>> easier to change git than the lustre filesystem software for a cluster
>> in running in production mode... (words from cluster team) :-/
>
> I thought you already established that simply disabling the progress
> display is a sufficient workaround? If that doesn't help, you can try
> patching out all use of SIGALRM within git.
>
> Other than that I agree with Junio, from what we've seen so far, Lustre
> returns EINTR on all sorts of calls that simply aren't allowed to do so.
>
--
---
Spécialiste en granularité (1 journée / semaine)
Calcul Québec / Calcul Canada
Pavillon Adrien-Pouliot, Université Laval, Québec (Québec), Canada
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-don-t-use-timers-if-NO_SETITIMER-is-set.patch --]
[-- Type: text/x-patch; name="0001-don-t-use-timers-if-NO_SETITIMER-is-set.patch", Size: 4069 bytes --]
>From 78eb4075d98eb9cdc57210c63b8d8de8a3d0cd9e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Boisvert?= <sebastien.boisvert@calculquebec.ca>
Date: Wed, 23 Jan 2013 13:10:57 -0500
Subject: [PATCH] don't use timers if NO_SETITIMER is set
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
With NO_SETITIMER, the user experience on legacy Lustre is fixed,
but there is no early progress.
The patch has no effect on the resulting git executable if NO_SETITIMER is
not set (the default). So by default this patch has no effect at all, which
is good.
git tests:
$ make clean
$ make NO_SETITIMER=YesPlease
$ make test NO_SETITIMER=YesPlease &> make-test.log
$ grep "^not ok" make-test.log |grep -v "# TODO known breakage"|wc -l
0
$ grep "^ok" make-test.log |wc -l
9531
$ grep "^not ok" make-test.log |wc -l
65
No timers with NO_SETITIMER:
$ objdump -d ./git|grep setitimer|wc -l
0
$ objdump -d ./git|grep alarm|wc -l
0
Timers without NO_SETITIMER:
$ objdump -d /software/apps/git/1.8.1/bin/git|grep setitimer|wc -l
5
$ objdump -d /software/apps/git/1.8.1/bin/git|grep alarm|wc -l
0
Signed-off-by: Sébastien Boisvert <sebastien.boisvert@calculquebec.ca>
---
builtin/log.c | 7 +++++++
daemon.c | 6 ++++++
progress.c | 8 ++++++++
upload-pack.c | 2 ++
4 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/builtin/log.c b/builtin/log.c
index 8f0b2e8..f8321c7 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -198,7 +198,9 @@ static void show_early_header(struct rev_info *rev, const char *stage, int nr)
printf(_("Final output: %d %s\n"), nr, stage);
}
+#ifndef NO_SETITIMER
static struct itimerval early_output_timer;
+#endif
static void log_show_early(struct rev_info *revs, struct commit_list *list)
{
@@ -240,9 +242,12 @@ static void log_show_early(struct rev_info *revs, struct commit_list *list)
* trigger every second even if we're blocked on a
* reader!
*/
+
+ #ifndef NO_SETITIMER
early_output_timer.it_value.tv_sec = 0;
early_output_timer.it_value.tv_usec = 500000;
setitimer(ITIMER_REAL, &early_output_timer, NULL);
+ #endif
}
static void early_output(int signal)
@@ -274,9 +279,11 @@ static void setup_early_output(struct rev_info *rev)
*
* This is a one-time-only trigger.
*/
+ #ifndef NO_SETITIMER
early_output_timer.it_value.tv_sec = 0;
early_output_timer.it_value.tv_usec = 100000;
setitimer(ITIMER_REAL, &early_output_timer, NULL);
+ #endif
}
static void finish_early_output(struct rev_info *rev)
diff --git a/daemon.c b/daemon.c
index 4602b46..eb82c19 100644
--- a/daemon.c
+++ b/daemon.c
@@ -611,9 +611,15 @@ static int execute(void)
if (addr)
loginfo("Connection from %s:%s", addr, port);
+ #ifndef NO_SETITIMER
alarm(init_timeout ? init_timeout : timeout);
+ #endif
+
pktlen = packet_read_line(0, line, sizeof(line));
+
+ #ifndef NO_SETITIMER
alarm(0);
+ #endif
len = strlen(line);
if (pktlen != len)
diff --git a/progress.c b/progress.c
index 3971f49..b84ccc7 100644
--- a/progress.c
+++ b/progress.c
@@ -45,7 +45,10 @@ static void progress_interval(int signum)
static void set_progress_signal(void)
{
struct sigaction sa;
+
+ #ifndef NO_SETITIMER
struct itimerval v;
+ #endif
progress_update = 0;
@@ -55,16 +58,21 @@ static void set_progress_signal(void)
sa.sa_flags = SA_RESTART;
sigaction(SIGALRM, &sa, NULL);
+ #ifndef NO_SETITIMER
v.it_interval.tv_sec = 1;
v.it_interval.tv_usec = 0;
v.it_value = v.it_interval;
setitimer(ITIMER_REAL, &v, NULL);
+ #endif
}
static void clear_progress_signal(void)
{
+ #ifndef NO_SETITIMER
struct itimerval v = {{0,},};
setitimer(ITIMER_REAL, &v, NULL);
+ #endif
+
signal(SIGALRM, SIG_IGN);
progress_update = 0;
}
diff --git a/upload-pack.c b/upload-pack.c
index 95d8313..e0b8b32 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -47,7 +47,9 @@ static int stateless_rpc;
static void reset_timeout(void)
{
+ #ifndef NO_SETITIMER
alarm(timeout);
+ #endif
}
static int strip(char *line, int len)
--
1.7.4.1
^ permalink raw reply related
* Re: [PATCH v3 1/8] git_remote_helpers: Allow building with Python 3
From: Sverre Rabbelier @ 2013-01-23 18:49 UTC (permalink / raw)
To: John Keeping; +Cc: Junio C Hamano, Git List
In-Reply-To: <72abc4652432c35ebb81404b41c2149d0400347a.1358686905.git.john@keeping.me.uk>
On Sun, Jan 20, 2013 at 5:15 AM, John Keeping <john@keeping.me.uk> wrote:
> Change inline Python to call "print" as a function not a statement.
>
> This is harmless because Python 2 will see the parentheses as redundant
> grouping but they are necessary to run this code with Python 3.
>
> Signed-off-by: John Keeping <john@keeping.me.uk>
Acked-by: Sverre Rabbelier <srabbelier@gmail.com>
--
Cheers,
Sverre Rabbelier
^ permalink raw reply
* Re: [PATCH v3 3/8] git_remote_helpers: Force rebuild if python version changes
From: Sverre Rabbelier @ 2013-01-23 18:51 UTC (permalink / raw)
To: John Keeping; +Cc: Junio C Hamano, Git List
In-Reply-To: <9a8644116bebf81cc15c0e63056bb2054dd17ebc.1358686905.git.john@keeping.me.uk>
On Sun, Jan 20, 2013 at 5:15 AM, John Keeping <john@keeping.me.uk> wrote:
> When different version of python are used to build via distutils, the
> behaviour can change. Detect changes in version and pass --force in
> this case.
>
> Signed-off-by: John Keeping <john@keeping.me.uk>
Someone else's review on this would be appreciated, the idea sounds
sane but I can't really comment on the implementation.
--
Cheers,
Sverre Rabbelier
^ permalink raw reply
* [PATCH] Ignore gitk-wish buildproduct
From: Lars Hjemli @ 2013-01-23 18:55 UTC (permalink / raw)
To: git; +Cc: Lars Hjemli
After running `make` on latest master, gitk-git/gitk-wish shows up as
untracked. This fixes it.
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
---
.gitignore | 1 +
1 file changed, 1 insertion(+)
diff --git a/.gitignore b/.gitignore
index aa258a6..63d4904 100644
--- a/.gitignore
+++ b/.gitignore
@@ -171,6 +171,7 @@
/git-whatchanged
/git-write-tree
/git-core-*/?*
+/gitk-git/gitk-wish
/gitweb/GITWEB-BUILD-OPTIONS
/gitweb/gitweb.cgi
/gitweb/static/gitweb.js
--
1.8.1.1.296.g725455c
^ permalink raw reply related
* Re: [PATCH v3 2/8] git_remote_helpers: fix input when running under Python 3
From: Sverre Rabbelier @ 2013-01-23 19:20 UTC (permalink / raw)
To: John Keeping; +Cc: Junio C Hamano, Git List
In-Reply-To: <7cd489e5b1b2578b1509232196cd6b21fd684843.1358686905.git.john@keeping.me.uk>
On Sun, Jan 20, 2013 at 5:15 AM, John Keeping <john@keeping.me.uk> wrote:
> Although 2to3 will fix most issues in Python 2 code to make it run under
> Python 3, it does not handle the new strict separation between byte
> strings and unicode strings. There is one instance in
> git_remote_helpers where we are caught by this, which is when reading
> refs from "git for-each-ref".
>
> Fix this by operating on the returned string as a byte string rather
> than a unicode string. As this method is currently only used internally
> by the class this does not affect code anywhere else.
>
> Note that we cannot use byte strings in the source as the 'b' prefix is
> not supported before Python 2.7 so in order to maintain compatibility
> with the maximum range of Python versions we use an explicit call to
> encode().
The three patches that deal with .encode() stuff (2, 7, 8) make me a
bit uncomfortable, as they add some significant complexity to our
python code. Is this the recommended way to deal with this (similar to
the other patch where you linked to the python wiki explaining)?
As one datapoint, it seems that it's actually Python 2.6 that
introduces the b prefix.
http://www.python.org/dev/peps/pep-3112/
When did we last revisit what minimal python version we are ok with requiring?
--
Cheers,
Sverre Rabbelier
^ permalink raw reply
* Git Merge 2013 Conference, Berlin
From: Scott Chacon @ 2013-01-23 19:27 UTC (permalink / raw)
To: git list
Hey all,
As you may remember, we did not have a GitTogether last year. Since I
miss drinking and talking Git nerdiness with all of you, I'm going to
try organizing some face time on a semi-regular basis. I would like
to try to do a small Git conference in the US and the EU each year.
We're starting off in Berlin, May 9-11th. GitHub has secured
conference space at the Radisson Blu Berlin for those days. I have a
smaller room for the first day so we can get 30-40 Git implementors
together to talk about the future of Git and whatnot. The second day
will be a user day where many more people can come in and talk about
how they use Git, what they would like to do with it, stuff they've
built on JGit or libgit2, issues they have, etc. The third day will
be a hack day where I can hold some training sessions for newbies and
all you hard core guys can hack on stuff in person.
There will be a dinner for implementors the first night and a drinkup
open to the public the second night.
It's going to be a really fun event, I hope you can make it. I set up
a website for the event here:
http://git-merge.com/
Scott
^ permalink raw reply
* Re: [PATCH v3 2/8] git_remote_helpers: fix input when running under Python 3
From: John Keeping @ 2013-01-23 19:47 UTC (permalink / raw)
To: Sverre Rabbelier; +Cc: Junio C Hamano, Git List
In-Reply-To: <CAGdFq_jp3BrS0zgDpmiXGduwu_m4E2CCL+X32P-7T=z9Qk-wuQ@mail.gmail.com>
On Wed, Jan 23, 2013 at 11:20:39AM -0800, Sverre Rabbelier wrote:
> On Sun, Jan 20, 2013 at 5:15 AM, John Keeping <john@keeping.me.uk> wrote:
> > Although 2to3 will fix most issues in Python 2 code to make it run under
> > Python 3, it does not handle the new strict separation between byte
> > strings and unicode strings. There is one instance in
> > git_remote_helpers where we are caught by this, which is when reading
> > refs from "git for-each-ref".
> >
> > Fix this by operating on the returned string as a byte string rather
> > than a unicode string. As this method is currently only used internally
> > by the class this does not affect code anywhere else.
> >
> > Note that we cannot use byte strings in the source as the 'b' prefix is
> > not supported before Python 2.7 so in order to maintain compatibility
> > with the maximum range of Python versions we use an explicit call to
> > encode().
>
> The three patches that deal with .encode() stuff (2, 7, 8) make me a
> bit uncomfortable, as they add some significant complexity to our
> python code. Is this the recommended way to deal with this (similar to
> the other patch where you linked to the python wiki explaining)?
The best I can offer is this:
http://docs.python.org/3/howto/pyporting.html#deal-with-the-bytes-string-dichotomy
Their recommendation is to use the b() function from the six project,
but given that we don't need it in too many places I prefer the approach
I took here to adding a thirdparty dependency.
> As one datapoint, it seems that it's actually Python 2.6 that
> introduces the b prefix.
>
> http://www.python.org/dev/peps/pep-3112/
>
> When did we last revisit what minimal python version we are ok with requiring?
I was wondering if people would weigh in discussing that in response to
[1] but no one has commented on that part of it. As another datapoint,
Brandon Casey was suggesting patching git-p4.py to support Python 2.4
[2].
[1] http://article.gmane.org/gmane.comp.version-control.git/213920
[2] http://article.gmane.org/gmane.comp.version-control.git/214048
John
^ permalink raw reply
* RE: Question re. git remote repository
From: Lang, David @ 2013-01-23 19:40 UTC (permalink / raw)
To: 'Matt Seitz', David Lang; +Cc: git@vger.kernel.org
In-Reply-To: <1BBEF94B6B46E54980290D150A6F2EDD46B7D7D0@BN1PRD0612MB635.namprd06.prod.outlook.com>
Thanks Matt and Dave and everyone else for your feedback on this.
Ok, I've done some more reading in the Pro Git manual and I think I have an idea of how to get started. Could I run this by you just in case I'm missing anything? Currently (pre-git status) what we have is two developers both working in Visual Studio, occasionally on the same project (hence the need for git). All the VS projects exist on a server and are accessible to both developers via a network share. Currently, if one of us needs to work on a project we turn around and ask our colleague if he's currently in it...this is how we avoid both being in at the same time. We run VS locally on each of our PC's and load the VS project into Visual Studio from the network share. Easy enough...
So to get this all set up with git, here's what I think I have to do...
1. Download and install git for Windows on the 2 networked developer's PC's and the 1 networked server.
2. On the server...
a) Initialize the Visual Studio folder for a particular project as a git repository using 'git init'
b) Using the git rep just created (above), create a bare repository on the server to act as the remote/master repository using 'git clone --bare'
3. On each of the PC's...
a) Clone the remote repository from the network server using 'git clone' (this will automatically create 'origin' as a remote source on the PC's)
Couple of questions...
1. Anyone see any problems/issues with the above?
2. Is it sufficient to use the local protocol for transferring files? Seems like the most straightforward.
3. On p.84 of the guide there's a section entitled "Putting the Bare Repository on a Server" but since the first two rep's (original and bare) are already on the server, this is unnecessary, correct?
4. The original Visual Studio project folder essentially remains untouched, correct? The 'git init' and 'git clone' commands just make copies and references of whatever data is in the VS project folder, right?
David
> -----Original Message-----
> From: git-owner@vger.kernel.org [mailto:git-owner@vger.kernel.org] On
>
> But ultimately, there shouldn't be a question of "if" you have a
> master repository but "where" you have the master repository, correct?
> Or in other words, it doesn't seem like you'd want to designate any
> one developer's local repository as also being the master repository, right?
You have two options:
1. Central model:
a. each developer has their own private repository b. each developer uses "git commit" to commit changes into their own private repository c. in addition, you also have a shared master repository d. each developer uses "git push" to push their changes from their private repository to the shared master repository e. each developer uses "git pull" to pull other developers' changes from the shared master repository
2. Peer-to-peer model:
a. each developer has their own private repository b. each developer uses "git commit" to commit changes into their own private repository c. each developer uses "git pull" to pull other developers' changes from other developers' private repositories
You can even mix these models. Say you have a 5 member team, and 2 members are working on a feature together. The 2 people working on the feature may use "git pull" to pull changes from each other's private repositories. Then, when the feature is ready, one of them can use "git push" to push the final version from their private repository into the team's shared repository.
What you don't want to do is this:
Single repository, multiple developers: just one repository, and every developer uses "git commit" to commit their changes into the same repository.
> My sense is that would defeat the purpose of the DVCS.
Not at all. The purpose of the DVCS is to allow each developer to have their own private repository where they can commit changes, while still allowing people to share changes from one repository to another. That's true whether you use the central model or the peer-to-peer model.
The traditional VCS has just one repository, and everyone has to commit their changes into that one central repository.
> We have access to many servers on our
> company's network, some of which we have full rights to, so there's no
> issue in regards to storage space.
That will work fine.
> I suppose another idea would be to have the master simply reside on
> one of the two developers local machines, so one of us would have both
> a local rep and the master rep and the other of us would have just a
> local rep.
That will also work. You could even omit the master rep. and just have each developer have a local repository. Each developer could then commit changes to their own local repository, and pull the other developer's changes from the other developer's local repository (the peer-to-peer model mentioned above).
> Or is it best to
> always have the master hosted on a machine with no other local reps?
There's no requirement to have the master hosted on a machine with no other local reps. The only issue is that the machine with the master rep. must be turned on for the other developers to push changes from their private repositories to the master repository. Having the master repository on a 24x7 server ensures it is always available to all developers. It also gives you another backup copy of your code, in case the developer's machine's storage fails or gets corrupted.
This e-mail may contain confidential and/or privileged information for the sole use of the intended recipient.
Any review or distribution by anyone other than the person for whom it was originally intended is strictly prohibited.
If you have received this e-mail in error, please contact the sender and delete all copies.
Opinions, conclusions or other information contained in this e-mail may not be that of the organization.
^ permalink raw reply
* Re: [PATCH] Ignore gitk-wish buildproduct
From: Junio C Hamano @ 2013-01-23 19:58 UTC (permalink / raw)
To: Lars Hjemli, Paul Mackerras; +Cc: git
In-Reply-To: <1358967340-3642-1-git-send-email-hjemli@gmail.com>
Lars Hjemli <hjemli@gmail.com> writes:
> After running `make` on latest master, gitk-git/gitk-wish shows up as
> untracked. This fixes it.
>
> Signed-off-by: Lars Hjemli <hjemli@gmail.com>
The removal was very much deliberate [*1*]; Christian was going to
send a corresponding updates to gitk maintainer [*2*, *3*] but I
guess we haven't sync'ed up yet.
Paul, I'll resend another copy of [*3*] to you as a follow-up;
please apply, thanks.
[References]
*1* http://thread.gmane.org/gmane.comp.version-control.git/211773
*2* http://thread.gmane.org/gmane.comp.version-control.git/211641/focus=211751
*3* http://thread.gmane.org/gmane.comp.version-control.git/213067
>
> ---
> .gitignore | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/.gitignore b/.gitignore
> index aa258a6..63d4904 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -171,6 +171,7 @@
> /git-whatchanged
> /git-write-tree
> /git-core-*/?*
> +/gitk-git/gitk-wish
> /gitweb/GITWEB-BUILD-OPTIONS
> /gitweb/gitweb.cgi
> /gitweb/static/gitweb.js
^ permalink raw reply
* [PATCH v3 0/2] Add git-for-each-repo
From: Lars Hjemli @ 2013-01-23 19:59 UTC (permalink / raw)
To: git; +Cc: Lars Hjemli
Lars Hjemli (2):
for-each-repo: new command used for multi-repo operations
git: rewrite `git -a` to become a git-for-each-repo command
.gitignore | 1 +
Documentation/git-for-each-repo.txt | 62 +++++++++++++++++++
Makefile | 1 +
builtin.h | 1 +
builtin/for-each-repo.c | 119 ++++++++++++++++++++++++++++++++++++
git.c | 37 +++++++++++
t/t6400-for-each-repo.sh | 54 ++++++++++++++++
7 files changed, 275 insertions(+)
create mode 100644 Documentation/git-for-each-repo.txt
create mode 100644 builtin/for-each-repo.c
create mode 100755 t/t6400-for-each-repo.sh
--
1.8.1.1.350.g3346805
^ permalink raw reply
* [PATCH v3 1/2] for-each-repo: new command used for multi-repo operations
From: Lars Hjemli @ 2013-01-23 19:59 UTC (permalink / raw)
To: git; +Cc: Lars Hjemli
In-Reply-To: <1358971180-10652-1-git-send-email-hjemli@gmail.com>
When working with multiple, unrelated (or loosly related) git repos,
there is often a need to locate all repos with uncommitted work and
perform some action on them (say, commit and push). Before this patch,
such tasks would require manually visiting all repositories, running
`git status` within each one and then decide what to do next.
This mundane task can now be automated by e.g. `git for-each-repo --dirty
status`, which will find all git repositories below the current directory
(even nested ones), check if they are dirty (as defined by `git diff --quiet
&& git diff --cached --quiet`), and for each dirty repo print the path to
the repo and then execute `git status` within the repo.
The command also honours the option '--clean' which restricts the set of
repos to those which '--dirty' would skip.
Finally, the command to execute within each repo is optional. If none is
given, git-for-each-repo will just print the path to each repo found.
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
---
.gitignore | 1 +
Documentation/git-for-each-repo.txt | 62 +++++++++++++++++++
Makefile | 1 +
builtin.h | 1 +
builtin/for-each-repo.c | 119 ++++++++++++++++++++++++++++++++++++
git.c | 1 +
t/t6400-for-each-repo.sh | 48 +++++++++++++++
7 files changed, 233 insertions(+)
create mode 100644 Documentation/git-for-each-repo.txt
create mode 100644 builtin/for-each-repo.c
create mode 100755 t/t6400-for-each-repo.sh
diff --git a/.gitignore b/.gitignore
index 63d4904..5036b84 100644
--- a/.gitignore
+++ b/.gitignore
@@ -56,6 +56,7 @@
/git-filter-branch
/git-fmt-merge-msg
/git-for-each-ref
+/git-for-each-repo
/git-format-patch
/git-fsck
/git-fsck-objects
diff --git a/Documentation/git-for-each-repo.txt b/Documentation/git-for-each-repo.txt
new file mode 100644
index 0000000..be49e96
--- /dev/null
+++ b/Documentation/git-for-each-repo.txt
@@ -0,0 +1,62 @@
+git-for-each-repo(1)
+====================
+
+NAME
+----
+git-for-each-repo - Execute a git command in multiple repositories
+
+SYNOPSIS
+--------
+[verse]
+'git for-each-repo' [--all|--clean|--dirty] [command]
+
+DESCRIPTION
+-----------
+The git-for-each-repo command is used to locate all git repositoris
+within the current directory tree, and optionally execute a git command
+in each of the found repos.
+
+OPTIONS
+-------
+-a::
+--all::
+ Include both clean and dirty repositories (this is the default
+ behaviour of `git-for-each-repo`).
+
+-c::
+--clean::
+ Only include repositories with a clean worktree.
+
+-d::
+--dirty::
+ Only include repositories with a dirty worktree.
+
+EXAMPLES
+--------
+
+Various ways to exploit this command::
++
+------------
+$ git for-each-repo <1>
+$ git for-each-repo fetch <2>
+$ git for-each-repo -d gui <3>
+$ git for-each-repo -c push <4>
+------------
++
+<1> Print the path to all repos found below the current directory.
+
+<2> Fetch updates from default remote in all repos.
+
+<3> Start linkgit:git-gui[1] in each repo containing uncommitted changes.
+
+<4> Push the current branch in each repo with no uncommited changes.
+
+NOTES
+-----
+
+For the purpose of `git-for-each-repo`, a dirty worktree is defined as a
+worktree with uncommitted changes.
+
+GIT
+---
+Part of the linkgit:git[1] suite
diff --git a/Makefile b/Makefile
index a786d4c..8c42c17 100644
--- a/Makefile
+++ b/Makefile
@@ -870,6 +870,7 @@ BUILTIN_OBJS += builtin/fetch-pack.o
BUILTIN_OBJS += builtin/fetch.o
BUILTIN_OBJS += builtin/fmt-merge-msg.o
BUILTIN_OBJS += builtin/for-each-ref.o
+BUILTIN_OBJS += builtin/for-each-repo.o
BUILTIN_OBJS += builtin/fsck.o
BUILTIN_OBJS += builtin/gc.o
BUILTIN_OBJS += builtin/grep.o
diff --git a/builtin.h b/builtin.h
index 7e7bbd6..02fc712 100644
--- a/builtin.h
+++ b/builtin.h
@@ -73,6 +73,7 @@ extern int cmd_fetch(int argc, const char **argv, const char *prefix);
extern int cmd_fetch_pack(int argc, const char **argv, const char *prefix);
extern int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix);
extern int cmd_for_each_ref(int argc, const char **argv, const char *prefix);
+extern int cmd_for_each_repo(int argc, const char **argv, const char *prefix);
extern int cmd_format_patch(int argc, const char **argv, const char *prefix);
extern int cmd_fsck(int argc, const char **argv, const char *prefix);
extern int cmd_gc(int argc, const char **argv, const char *prefix);
diff --git a/builtin/for-each-repo.c b/builtin/for-each-repo.c
new file mode 100644
index 0000000..9bdeb4a
--- /dev/null
+++ b/builtin/for-each-repo.c
@@ -0,0 +1,119 @@
+/*
+ * "git for-each-repo" builtin command.
+ *
+ * Copyright (c) 2013 Lars Hjemli <hjemli@gmail.com>
+ */
+#include "cache.h"
+#include "color.h"
+#include "builtin.h"
+#include "run-command.h"
+#include "parse-options.h"
+
+#define ALL 0
+#define DIRTY 1
+#define CLEAN 2
+
+static int match;
+
+static const char * const builtin_foreachrepo_usage[] = {
+ N_("git for-each-repo [--all|--clean|--dirty] [cmd]"),
+ NULL
+};
+
+static struct option builtin_foreachrepo_options[] = {
+ OPT_SET_INT('a', "all", &match, N_("match both clean and dirty repositories"), ALL),
+ OPT_SET_INT('c', "clean", &match, N_("only show clean repositories"), CLEAN),
+ OPT_SET_INT('d', "dirty", &match, N_("only show dirty repositories"), DIRTY),
+ OPT_END(),
+};
+
+static int get_repo_state()
+{
+ const char *diffidx[] = {"diff", "--quiet", "--cached", NULL};
+ const char *diffwd[] = {"diff", "--quiet", NULL};
+
+ if (run_command_v_opt(diffidx, RUN_GIT_CMD) != 0)
+ return DIRTY;
+ if (run_command_v_opt(diffwd, RUN_GIT_CMD) != 0)
+ return DIRTY;
+ return CLEAN;
+}
+
+static void handle_repo(char *path, const char **argv)
+{
+ if (path[0] == '.' && path[1] == '/')
+ path += 2;
+ if (match != ALL && match != get_repo_state())
+ return;
+ if (*argv) {
+ color_fprintf_ln(stdout, GIT_COLOR_YELLOW, "[%s]", path);
+ run_command_v_opt(argv, RUN_GIT_CMD);
+ } else
+ printf("%s\n", path);
+}
+
+static int walk(struct strbuf *path, int argc, const char **argv)
+{
+ DIR *dir;
+ struct dirent *ent;
+ struct stat st;
+ size_t len;
+ const char *gitdir;
+
+ dir = opendir(path->buf);
+ if (!dir)
+ return errno;
+ strbuf_addstr(path, "/");
+ len = path->len;
+ while ((ent = readdir(dir))) {
+ if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
+ continue;
+ if (!strcmp(ent->d_name, ".git")) {
+ strbuf_addstr(path, ent->d_name);
+ gitdir = resolve_gitdir(path->buf);
+ if (!gitdir) {
+ strbuf_setlen(path, len - 1);
+ strbuf_addstr(path, "/");
+ continue;
+ }
+ setenv(GIT_DIR_ENVIRONMENT, gitdir, 1);
+ strbuf_setlen(path, len - 1);
+ setenv(GIT_WORK_TREE_ENVIRONMENT, path->buf, 1);
+ handle_repo(path->buf, argv);
+ strbuf_addstr(path, "/");
+ continue;
+ }
+ strbuf_setlen(path, len);
+ strbuf_addstr(path, ent->d_name);
+ switch (DTYPE(ent)) {
+ case DT_UNKNOWN:
+ case DT_LNK:
+ /* Use stat() to figure out if this path leads
+ * to a directory - it's not important if it's
+ * a symlink which gets us there.
+ */
+ if (stat(path->buf, &st) || !S_ISDIR(st.st_mode))
+ break;
+ /* fallthrough */
+ case DT_DIR:
+ walk(path, argc, argv);
+ break;
+ }
+ strbuf_setlen(path, len);
+ }
+ closedir(dir);
+ return 0;
+}
+
+int cmd_for_each_repo(int argc, const char **argv, const char *prefix)
+{
+ struct strbuf path = STRBUF_INIT;
+
+ argc = parse_options(argc, argv, prefix,
+ builtin_foreachrepo_options,
+ builtin_foreachrepo_usage,
+ PARSE_OPT_STOP_AT_NON_OPTION);
+
+ strbuf_addstr(&path, ".");
+ return walk(&path, argc, argv);
+}
diff --git a/git.c b/git.c
index ed66c66..6b53169 100644
--- a/git.c
+++ b/git.c
@@ -337,6 +337,7 @@ static void handle_internal_command(int argc, const char **argv)
{ "fetch-pack", cmd_fetch_pack, RUN_SETUP },
{ "fmt-merge-msg", cmd_fmt_merge_msg, RUN_SETUP },
{ "for-each-ref", cmd_for_each_ref, RUN_SETUP },
+ { "for-each-repo", cmd_for_each_repo },
{ "format-patch", cmd_format_patch, RUN_SETUP },
{ "fsck", cmd_fsck, RUN_SETUP },
{ "fsck-objects", cmd_fsck, RUN_SETUP },
diff --git a/t/t6400-for-each-repo.sh b/t/t6400-for-each-repo.sh
new file mode 100755
index 0000000..4797629
--- /dev/null
+++ b/t/t6400-for-each-repo.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+#
+# Copyright (c) 2013 Lars Hjemli
+#
+
+test_description='Test the git-for-each-repo command'
+
+. ./test-lib.sh
+
+test_expect_success "setup" '
+ test_create_repo clean &&
+ (cd clean && test_commit foo) &&
+ git init --separate-git-dir=.cleansub clean/gitfile &&
+ (cd clean/gitfile && test_commit foo && echo bar >>foo.t) &&
+ test_create_repo dirty-wt &&
+ (cd dirty-wt && mv .git .linkedgit && ln -s .linkedgit .git &&
+ test_commit foo && rm foo.t) &&
+ test_create_repo dirty-idx &&
+ (cd dirty-idx && test_commit foo && git rm foo.t) &&
+ mkdir fakedir && mkdir fakedir/.git
+'
+
+test_expect_success "without flags, all repos are included" '
+ echo "." >expect &&
+ echo "clean" >>expect &&
+ echo "clean/gitfile" >>expect &&
+ echo "dirty-idx" >>expect &&
+ echo "dirty-wt" >>expect &&
+ git for-each-repo | sort >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success "--dirty only includes dirty repos" '
+ echo "clean/gitfile" >expect &&
+ echo "dirty-idx" >>expect &&
+ echo "dirty-wt" >>expect &&
+ git for-each-repo --dirty | sort >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success "--clean only includes clean repos" '
+ echo "." >expect &&
+ echo "clean" >>expect &&
+ git for-each-repo --clean | sort >actual &&
+ test_cmp expect actual
+'
+
+test_done
--
1.8.1.1.350.g3346805
^ permalink raw reply related
* [PATCH v3 2/2] git: rewrite `git -a` to become a git-for-each-repo command
From: Lars Hjemli @ 2013-01-23 19:59 UTC (permalink / raw)
To: git; +Cc: Lars Hjemli
In-Reply-To: <1358971180-10652-1-git-send-email-hjemli@gmail.com>
With this rewriting, it is now possible to run e.g. `git -ad gui` to
start up git-gui in each repo within the current directory which
contains uncommited work.
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
---
git.c | 36 ++++++++++++++++++++++++++++++++++++
t/t6400-for-each-repo.sh | 6 ++++++
2 files changed, 42 insertions(+)
diff --git a/git.c b/git.c
index 6b53169..f933b5d 100644
--- a/git.c
+++ b/git.c
@@ -31,8 +31,42 @@ static void commit_pager_choice(void) {
}
}
+/*
+ * Rewrite 'git -ad status' to 'git for-each-repo -d status'
+ */
+static int rewrite_foreach_repo(const char ***orig_argv,
+ const char **curr_argv,
+ int *curr_argc)
+{
+ const char **new_argv;
+ char *tmp;
+ int new_argc, curr_pos, i, j;
+
+ curr_pos = curr_argv - *orig_argv;
+ if (strlen(curr_argv[0]) == 2) {
+ curr_argv[0] = "for-each-repo";
+ return curr_pos - 1;
+ }
+
+ new_argc = curr_pos + *curr_argc + 1;
+ new_argv = xmalloc(new_argc * sizeof(void *));
+ for (i = j = 0; j < new_argc; i++, j++) {
+ if (i == curr_pos) {
+ asprintf(&tmp, "-%s", (*orig_argv)[i] + 2);
+ new_argv[j] = "for-each-repo";
+ new_argv[++j] = tmp;
+ } else {
+ new_argv[j] = (*orig_argv)[i];
+ }
+ }
+ *orig_argv = new_argv;
+ (*curr_argc)++;
+ return curr_pos;
+}
+
static int handle_options(const char ***argv, int *argc, int *envchanged)
{
+ const char ***pargv = argv;
const char **orig_argv = *argv;
while (*argc > 0) {
@@ -143,6 +177,8 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
setenv(GIT_LITERAL_PATHSPECS_ENVIRONMENT, "0", 1);
if (envchanged)
*envchanged = 1;
+ } else if (!strncmp(cmd, "-a", 2)) {
+ return rewrite_foreach_repo(pargv, *argv, argc);
} else {
fprintf(stderr, "Unknown option: %s\n", cmd);
usage(git_usage_string);
diff --git a/t/t6400-for-each-repo.sh b/t/t6400-for-each-repo.sh
index 4797629..b501605 100755
--- a/t/t6400-for-each-repo.sh
+++ b/t/t6400-for-each-repo.sh
@@ -27,6 +27,8 @@ test_expect_success "without flags, all repos are included" '
echo "dirty-idx" >>expect &&
echo "dirty-wt" >>expect &&
git for-each-repo | sort >actual &&
+ test_cmp expect actual &&
+ git -a | sort >actual &&
test_cmp expect actual
'
@@ -35,6 +37,8 @@ test_expect_success "--dirty only includes dirty repos" '
echo "dirty-idx" >>expect &&
echo "dirty-wt" >>expect &&
git for-each-repo --dirty | sort >actual &&
+ test_cmp expect actual &&
+ git -ad | sort >actual &&
test_cmp expect actual
'
@@ -42,6 +46,8 @@ test_expect_success "--clean only includes clean repos" '
echo "." >expect &&
echo "clean" >>expect &&
git for-each-repo --clean | sort >actual &&
+ test_cmp expect actual &&
+ git -ac | sort >actual &&
test_cmp expect actual
'
--
1.8.1.1.350.g3346805
^ 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