Git development
 help / color / mirror / Atom feed
* [StGit PATCH] Test that we can add a new file to a non-topmost patch with refresh -p
From: Karl Hasselström @ 2008-07-18 17:03 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: git, Jon Smirl
In-Reply-To: <20080718084127.GA7042@diana.vm.bytemark.co.uk>

We currently can't -- this is bug 12038, found by Jon Smirl. See

  https://gna.org/bugs/index.php?12038

Signed-off-by: Karl Hasselström <kha@treskal.com>

---

Here's a proper test that demonstrates the bug. It applies to the
stable branch.

 t/t2701-refresh-p.sh |   46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 46 insertions(+), 0 deletions(-)
 create mode 100755 t/t2701-refresh-p.sh


diff --git a/t/t2701-refresh-p.sh b/t/t2701-refresh-p.sh
new file mode 100755
index 0000000..d42e90f
--- /dev/null
+++ b/t/t2701-refresh-p.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+test_description='Run "stg refresh -p"'
+
+. ./test-lib.sh
+
+# Ignore our own temp files.
+cat >> .git/info/exclude <<EOF
+expected*.txt
+files*.txt
+status*.txt
+EOF
+
+test_expect_success 'Initialize StGit stack' '
+    stg init &&
+    for i in 1 2; do
+        echo x > $i.txt &&
+        git add $i.txt &&
+        stg new p$i -m "Patch $i" &&
+        stg refresh
+    done
+'
+
+touch expected0.txt
+cat > expected1.txt <<EOF
+A 1.txt
+A new.txt
+EOF
+cat > expected2.txt <<EOF
+A 2.txt
+EOF
+test_expect_failure 'Add new file to non-top patch' '
+    stg status > status1.txt &&
+    diff -u expected0.txt status1.txt &&
+    echo y > new.txt &&
+    git add new.txt &&
+    stg refresh -p p1 &&
+    stg status > status2.txt &&
+    diff -u expected0.txt status2.txt &&
+    stg files p1 > files1.txt &&
+    diff -u expected1.txt files1.txt &&
+    stg files p2 > files2.txt &&
+    diff -u expected2.txt files2.txt
+'
+
+test_done

^ permalink raw reply related

* Re: Considering teaching plumbing to users harmful
From: Ping Yin @ 2008-07-18 17:02 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Avery Pennarun, Johannes Schindelin, git
In-Reply-To: <7vr69tpoze.fsf@gitster.siamese.dyndns.org>

On Thu, Jul 17, 2008 at 4:12 AM, Junio C Hamano <gitster@pobox.com> wrote:

> Suppose you are about to finish something you have been cooking (say a
> series of five logical commits), you've made three of these commits
> already, and what you have in your work tree and the index is to be split
> into the last two commits.  Somehow you learn that $x above has a updated
> version.
>
> Yes, running "git stash && git pull --rebase && git stash pop" would be
> better than running "git pull --rebase" alone from that state.  But that
> would mean your history would have your first 3 commits (of 5 commit
> series), somebody else's totally unrelated commits, and then you will work
> on finishing the remaining 2 commits on top of it.

Hmm, the first 3 commits are not pushed out, right? So by "rebase",
the history should be first the somebody else's commits
(origin/master), then the first 3 commits, then the remaining 2
commits?:


-- 
Ping Yin

^ permalink raw reply

* copy selected history between repostories
From: luisgutz @ 2008-07-18 16:58 UTC (permalink / raw)
  To: git


Hi All,

This is something I'm not sure how to do with git, or even if it is possible
in git; and because google has not been my friend this time, I though I
would ask here.

I have 2 repositories: repoA and repoB.

repoB is massive. lots of history and files. But it has a set of files
inside a particular dir with 40-60 files that I just realized are better in
repoA.

Is there any way to import that directory into repoA with all it's history,
but NOT the history from the other commits?
Another way of putting is this: can I make git forget the history of all
other commits but those from this directory?


-- 
View this message in context: http://www.nabble.com/copy-selected-history-between-repostories-tp18533605p18533605.html
Sent from the git mailing list archive at Nabble.com.

^ permalink raw reply

* Re: [PATCH 2/3] add new Git::Repo API
From: Petr Baudis @ 2008-07-18 16:54 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: Lea Wiemann, git, John Hawley
In-Reply-To: <200807150141.39186.jnareb@gmail.com>

On Tue, Jul 15, 2008 at 01:41:38AM +0200, Jakub Narebski wrote:
> On Mon, 14 July 2008, Petr Baudis wrote:
> > Here is an idea: Introduce Git::Command object that will have very
> > general interface and look like
> > 
> > 	my $c = Git::Command->new(['git', '--git-dir=.', 'cat-file', \
> > 		'-p', 'bla'], {pipe_out=>1})
> > 	...
> > 	$c->close();
> 
> Errr... how do you read from such a pipe?  <$c> I think wouldn't work,
> unless you would use some trickery...

That's good point; it might either be done using some trickery, or
$c->pipe. The idea behind having a special object for it though is to
have *unified* (no matter how simple) error handling. You might not
detect the command erroring out at the open time.

Is there a better approach for solving this?

> > and a Git::CommandFactory with a nicer interface that would look like
> > 
> > 	my $cf = Git::CommandFactory->new('git', '--git-dir=.');
> > 	my $c = $cf->output_pipe('cat-file', '-p', 'bla');
> > 	$c->close();
> > 
> > Then, Git::Repo would have a single Git::CommandFactory instance
> > pre-initialized with the required calling convention, and returned by
> > e.g. cmd() method. Then, from the user POV, you would just:
> > 
> > 	my $repo = Git::Repo->new;
> > 	$repo->cmd->output_pipe('cat-file', '-p', 'bla');
> > 
> > Or am I overdoing it?
> 
> You are probably overdoing it.
> 
> 
> I think it would be good to have the following interface
> 
> Git->output_pipe('ls-remotes', $URL, '--heads');

This is problematic; I think mixing the new and old interface within a
single class is very bad idea, we should have Git::Standalone or
something for this. Or, just, default Git::CommandFactory. ;-)

> [...]
> $r = Git::Repo->new(<git_dir>);
> $r->output_pipe('ls_tree', 'HEAD');
> [...]
> $nb = Git::Repo::NonBare->new(<git_dir>[, <working_area>]);
> $nb->output_pipe('ls-files');
> 
> 
> How can it be done with minimal effort, unfortunately I don't know...

Well, this interface is almost identical to what I delineated, except
that I have the extra ->cmd-> step there. But maybe, we could go with
your API and instead have Git::CommandFactory as a base of Git::Repo?
The hierarchy would be

	Git::CommandFactory - provides the cmd_pipe toolkit
		|
	    Git::Repo       - provides repository model
		|
	Git::Repo::NonBare  - additional working-copy-related methods

I think I will post a sample implementation sometime over the weekend.

> > Another thing is clearly describing how error handling is going to work.
> > I have not much against ditching Error.pm, but just saying "die + eval"
> > does not cut it - how about possible sideband data? E.g. the failure
> > mode of Git.pm's command() method includes passing the error'd command
> > output in the exception object. How are we going to handle it? Now, it
> > might be actually okay to say that we _aren't_ going to handle this if
> > it is deemed unuseful, but that needs to be determined too. I don't know
> > off the top of my head.
> 
> I think that the solution might be some output_pipe option on how to
> treat command exit status, command STDERR, and errors when invoking
> command (for example command not found).
> 
> Mentioned http://http://www.perl.com/pub/a/2002/11/14/exception.html
> explains why one might want to use Error.pm.

The arguments against its usage that popped up over the year(s?):

	(i) It is not standard practice in the Perl world

	(ii) It is syntactically ambiguous, c.f. Lea's report about
	the missing semicolon

	(iii) The usage of closures in this way has inherent memory leak
	issues

-- 
				Petr "Pasky" Baudis
As in certain cults it is possible to kill a process if you know
its true name.  -- Ken Thompson and Dennis M. Ritchie

^ permalink raw reply

* Re: [PATCH 2/3] add new Git::Repo API
From: Lea Wiemann @ 2008-07-18 16:51 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git, John Hawley, Petr Baudis
In-Reply-To: <200807181735.15278.jnareb@gmail.com>

Jakub Narebski wrote:
> Besides if decoding is done in Perl API, we can convert it simply
> to Perl internal form (which, IIUC, in modern Perl is UTF-8 and
> marked as such).

FWIW, Perl strings actually contain non-encoded Unicode code points.
IOW, they're not byte strings.

> Still I think that putting cmd_output and other in Git::Repo
> is not a good API.

Yup; that's why I'm underscore-prefixing it (and taking it out of the
man page) for the next version of this patch.

> By the way, would you prefer if I commented on 3/3 patch as it is now,
> [...] or would you rather I wait for next round (next version) of patches?

I suggest you wait for the next version of the patch series, which I'll
post in a few hours.  There are quite a few changes; I'll list them in
the parent message for the series.

-- Lea

^ permalink raw reply

* Re: [PATCH 2/3] add new Git::Repo API
From: Petr Baudis @ 2008-07-18 16:48 UTC (permalink / raw)
  To: Lea Wiemann, Jakub Narebski; +Cc: git, John Hawley
In-Reply-To: <487BD0F3.2060508@gmail.com>

In order to keep this mail within sensible size, I have trimmed some of
the bits - basically, the default reply is usually ranging from "Fair
enough" to "Great!" :-)

On Tue, Jul 15, 2008 at 12:19:31AM +0200, Lea Wiemann wrote:
> > First, I don't think it's good idea at all to put the pipe-related stuff
> > to Git::Repo - this is botched up API just like the current one.
> 
> Well, they're more like helper methods.  Since they don't fit into the
> design goals of the Git::Repo API at all, I'd suggest we just
> underscore-prefix them and take them out of the man page.  (The only
> reason why I hadn't done this is that gitweb uses $repo->cmd_output
> extensively, so it'd end up with a lot of underscore calls.  But I
> suppose we can either alias _cmd_output to cmd_output in gitweb's
> CachedRepo subclass, or live with $repo->_cmd_output calls.)  Does
> underscore-prefixing sound good to you?

I think this is one problematic point we keep hitting - my opinion is
that we _need_ such a wrapper _publically_, because it tends to be
actually the main use-case of Git.pm, and that this wrapper should be:

	(i) both available standalone for commands like ls-remote

	(ii) and available as part of Git::Repo instance, to have the
	right arguments passed to Git automagically

So you define cmd_output() and seem to argue that this command should
not be called directly and is not interesting for the outside. But the
experience shows that the pipe interface is actually the _most_ used
part of the Git Perl API, and in fact you mentioned that as part of your
gitweb migration to Git::Repo, you will temporarily introduce calls to
_cmd_output(), the "internal" API. :-) Sure, it's only temporary, but
many won't have the luxury to adjust the Git::Repo API to provide all
the operations they need, and ultimately they will need to defer to the
pipe interface.

> > It should be actually very easy to start with moving all the pipe
> > functionality to Git::Command.
> 
> Creating a new (Git::Command) API is very much non-trivial, apart from
> the fact that I'm not convinced that we need Git::Command, and that a
> clean command interface neither falls out of Git.pm nor Git::Repo.

As I said, majority of Git API usage is actually the pipe API. So we
should figure out how to provide it. I agree that it's not immediately
within your scope, but you are introducing new Perl API and this just
needs to be embedded somewhere there consistently.

> >> [Git::Commit->new, Git::Tag->new:]
> >> +Calls to this method are free, since it does not check whether $sha1
> >> +exists and has the right type.  However, accessing any of the commit
> >> +object's properties will fail if $sha1 is not a valid commit object.
> > 
> > This is nice idea, but I'd also provide a well-defined way for the user
> > to verify the object's validity at a good moment; basically, make load()
> > a public method. The user can deal with errors then and rely on
> > error-free behavior later.
> 
> No, you should never pass in an invalid SHA1 in the first place.  The
> above piece of documentation is just a warning that bugs will show up
> delayed.  IOW, this is not the right place to have your error handling.
> 
> If you're getting a SHA1 through the user-interface, check its existence
> with get_sha1 before passing it to the constructor.

But that's an expensive operation, you need extra Git exec for this,
while all the Git commands can do the checks for you, if you give them
the chance.

I was doing pretty much this thing in Cogito (initially out of
necessity) and it made it ungodly slow for any kind of batch operations.

> >> +Note that $sha1 must be the SHA1 of a commit object; tag objects are
> >> +not dereferenced.
> > 
> > Why not?
> 
> Because the SHA1 might resolve to an object of the wrong type, which
> means you have to do error handling in Git::Object objects; that's the
> wrong place.
> 
> If tag-resolving is really needed, we can add an optional $type
> parameter to get_sha1, which will cause get_sha1 to resolve the object
> until a $type object is found, or return undef if the object is or
> resolves to an object of the wrong type.

See above why I think you should reconsider requiring the explicit
"resolving" step.

> I have resolving code in gitweb's git_get_sha1_or_die (which I didn't
> implement in Git::Repo since it uses some customized error reporting).
> The resolving code could conceivably be extracted and moved to get_sha1.
>  I think there are a few things to ponder and maybe discuss, so I'd do
> that in a separate patch (if I get around it before the end of the project).

The thing that concerns me about this is that this might show that your
approach to error handling is not flexible enough for some real-world
usage and this might be a design mistake - is that not so? I didn't look
at the code.

> >> [Snipped a lot of quoting --LW]
> >> +=item $repo->repo_dir
> >> +=item $repo->git_binary
> >> +=item $repo->version
> >> +sub _get_git_cmd {
> > 
> > This definitely does not belong to a Git::Repo object.
> 
> Which of those methods are you referring to?  I think $repo->version
> might reasonably be removed (and the code re-added to gitweb); I'll do
> so unless you object.  _get_git_cmd is already underscored, and repo_dir
> and git_binary only access attributes passed in through the constructor,
> so I think those three should stay.

Sorry, you're right about repo_dir and possibly git_binary. My main
concern was about the command pipe handling itself, but I elaborated on
that above already.

> >> +=item $repo->get_refs
> >> +=item $repo->get_refs($pattern)
> > 
> > Again, the refs should be properly integrated into the object structure.
> 
> Really?  I think it's generally fine for get_refs to exist and to live
> in Git::Repo.
> 
> Its return value (currently an an arrayref of [$sha1, $object_type,
> $ref_name] arrayrefs) might need improvement though, and I find the
> $pattern parameter pretty suspect (in that it smells like a for-each-ref
> wrapper).  Since get_refs is unused at the moment (gitweb ended up
> needing the slightly different show-ref), I'll remove it for now.  (Same
> thing about me not being a fan of premature API design applies.)

Just a note, the thing is that you might want to add some methods for
inspecting and mutating the refs, and at the same time this is not a
repository-specific concept, but you can get the same structure from
git ls-remote call. That's why I think it would make sense to make
a separate object out of it. But that's moot point now that the API
won't be there yet.

-- 
				Petr "Pasky" Baudis
As in certain cults it is possible to kill a process if you know
its true name.  -- Ken Thompson and Dennis M. Ritchie

^ permalink raw reply

* Re: git submodules and commit
From: Ping Yin @ 2008-07-18 16:11 UTC (permalink / raw)
  To: Avery Pennarun; +Cc: Nigel Magnay, Git Mailing List
In-Reply-To: <32541b130807160843k25f1d7d3u8bfecd6c1c6eab91@mail.gmail.com>

On Wed, Jul 16, 2008 at 11:43 PM, Avery Pennarun <apenwarr@gmail.com> wrote:
> On 7/16/08, Nigel Magnay <nigel.magnay@gmail.com> wrote:

> If you want to work with me on my new submodule workflow (and I'd
> certainly appreciate it!) then I'd suggest one or more of the
> following starting points:
>
> - Take the recursive push, pull, and update operations described
> above, make them general (ie. not referring to my submodules by name
> :)), and add them as commands in the real git-submodule script.  The
> trickiest part here will be figuring out which remote branch to
> push/pull.

See http://article.gmane.org/gmane.comp.version-control.git/69834
([PATCH] Added recurse command to git submodule)
Or search "submodule recursive" in gmane.

The recursive pull,diff,status for submodule is implemented by Imran M
Yousuf. And IIRC, with this patch, you can walk through the submodule
hierarchy to exectute any command.




-- 
Ping Yin

^ permalink raw reply

* Re: [PATCH] Teach git submodule update to use distributed repositories
From: Petr Baudis @ 2008-07-18 15:49 UTC (permalink / raw)
  To: Nigel Magnay; +Cc: Johannes Schindelin, Git Mailing List
In-Reply-To: <320075ff0807180809x599aefafw2c7fe88fea2691d2@mail.gmail.com>

On Fri, Jul 18, 2008 at 04:09:40PM +0100, Nigel Magnay wrote:
> Hmm. Locally modifying my .gitmodules still feels bad because I don't
> like either of those tradeoffs (but I don't have any sensible
> suggestion yet).
> 
> As a bit of background (as to why I'd dislike (a) and (b)), we had a
> team switch to git, and one of the really nice things is the ability
> to share stuff around and branch freely - but the flipside of that is
> that we tend to push to a central repo more rarely, so the advantages
> of an continuous integration server become less. What we did is to
> tell a centralised CI server the URLs of all the team's git
> repositories, and it would periodically pull from them, speculatively
> compile anything new, and run the big suite of tests - finishing up by
> emailling them a heads-up that a particular state in their repo is
> 'bad'.
> 
> This was really popular as it was demonstrably better than anything we
> could do with svn, and best of all, it's pretty much transparent - as
> a user you don't have to do anything at all.
> 
> I could do it now by hacking about with files; it'd just be nice to
> keep it transparent and make it a directly supported feature.

In that case you would need the "URL mappings", perhaps as a per-remote
attribute. That is, you could configure:

	"When I am doing git pull fred, do git submodule update but
	apply remote.fred.subrewrite sed script on each URL before
	fetching the submodule."

Still, that feels quite hackish to me, and I'm not convinced that your
workflow cannot be adjusted so that users merge only the next-to-last
commit of a branch instead of the last one.

-- 
				Petr "Pasky" Baudis
As in certain cults it is possible to kill a process if you know
its true name.  -- Ken Thompson and Dennis M. Ritchie

^ permalink raw reply

* Re: [PATCH 2/3] add new Git::Repo API
From: Jakub Narebski @ 2008-07-18 15:35 UTC (permalink / raw)
  To: Lea Wiemann; +Cc: git, John Hawley, Petr Baudis
In-Reply-To: <48809D31.5030008@gmail.com>

Lea Wiemann wrote:
> Jakub Narebski wrote:

>>>>> +=item $commit->message
>> 
>> I'd rather then have _git_ convert it to UTF=8 for us (using 
>> --encoding=<encoding> option to git-log/git-rev-list)
> 
> Yeah, I guess the API should actually decode it.  You wouldn't want to
> have the message in UTF-8 but in Unicode (I suggest you read man
> perlunitut if you haven't done so).

You mean perluniintro(1) here, isn't it?

Besides if decoding is done in Perl API, we can convert it simply
to Perl internal form (which, IIUC, in modern Perl is UTF-8 and
marked as such).

> We cannot have git do the decoding, 
> since (apart from the fact that it doesn't smell right) it isn't
> guaranteed to emit valid UTF-8 [...]

Well, if that is the case then Perl API has to do conversion, that
is the only sensible way.

>> It is (much) better than forking git-cat-file for each commit shown
>> on the list; nevertheless I think that it would be better to use git-log
>> to generate list (or Git::Revlist) of Git::Commit objects.  It is one
>> fork less, but what more important you don't have to access repository
>> twice for the very same objects.
> 
> You're confused; it's not one fork less, it's a write to a pipe less.
> (Pleeeease look at the code before you write something.  It's there, in
> this very thread.)  And I don't believe the "access the repository
> twice" thing is anywhere near an actual issue.  To summarize, you're
> asking me to (a) write code and (presumably) (b) add something to the
> interface of a public API, based on some (most probably faulty)
> assumptions about performance?  You should really read
> <http://c2.com/cgi/wiki?PrematureOptimization>.

Code is there, in gitweb, in parse_commits subroutine, or rather in
parse_commit_text subroutine.

[cut]

But I can agree that possible (and possibly minuscule) performance
improvement is not worth introducing new API and complicating (I think)
gitweb code.
 
>> I think that _not using_ Git::Cmd (or somesuch) API results in botched,
>> horrible API
>>   our $git_version = $repo_root->repo(directory => 'dummy')->version;
>> (Unless it is not needed any longer, or not used any longer; if it is
>> so, then perhaps implementing Git::Cmd as generic wrapper around git
>> commands, hiding for example ActivePerl hack, could be left for later).
> 
> It isn't used any longer -- I really suggest you read the whole thread
> before replying. ;-)

O.K.  Still I think that putting cmd_output and other in Git::Repo
is not a good API. I'd rather route calling git commands via Git or
Git::Cmd object (but Git::Repo would have Git/Git::Cmd object which
automatically adds '--git-dir=<path>', and possibly also
'--work-dir=<path>').

By the way, would you prefer if I commented on 3/3 patch as it is now,
taking into account what I remember from discussion on this and 2/3
patch (latter only as relevant), or would you rather I wait for next
round (next version) of patches?
 
>>> I wouldn't -- see my blurb about error handling at the top of my reply
>>> to Petr (<487BD0F3.2060508@gmail.com>).  You're not supposed to pass
>>> anything that you didn't get from get_sha1 into Git::Commit or
>>> Git::Tag constructors, or your error handling is invariably broken.
>> 
>> I can understand this simpler, although less than optimal, and geared
>> mainly towards gitweb needs.
> 
> FTR, yes it is simpler, but no, it is not really geared toward gitweb
> needs, and it's definitely not "less than optimal" in the sense of being
> worse than the exception-based error handling Git.pm does.  Trust on me
> on this one. ;-)

[...]

>> Why do you _need_ name_rev, if you are not to include git-describe
>> equivalent?
> 
> I needed it for gitweb.  As I said, I'm not trying to create a complete
> API.  A describe_rev (or so) method can be added later, if and when it's
> needed.  (As I said, I don't think writing APIs without at least one use
> case is a good idea anyway.)

Errr... I guess I misspoke. I should not say 'geared toward gitweb
needs', as perhaps it is 'created according [at least somewhat] to
what gitweb would need'.
 
-- 
Jakub Narebski
Poland

^ permalink raw reply

* Re: [PATCH] Teach git submodule update to use distributed repositories
From: Nigel Magnay @ 2008-07-18 15:09 UTC (permalink / raw)
  To: Petr Baudis; +Cc: Johannes Schindelin, Git Mailing List
In-Reply-To: <20080718144325.GR10151@machine.or.cz>

>> Ah - I understand. You're saying "you can't pull submodules when you
>> pull the supermodule, because you don't know which submodules might be
>> needed until you also merge / checkout the desired revision" ?
>>
>> Ack.
>
> That is something I might agree with, but my point is that within the
> submodule,
>
>        git pull
>
> simply isn't a sensible operation at all! You don't want to do any
> merges or whatever, just bring the submodule to a defined commit id.
> So you want to do something significantly different:
>
>        git fetch
>        git reset --hard <commitid>
>
> And that's what 'git submodule update' already does.
>

I wasn't wanting to do pull there - but either way, I agree :-)

>> Hm. It feels like each person could have some 'local' info in their
>> .gitmodules, and rules around merging; but I'm not sure of exactly
>> what, or how.
>
> Again, when customizing .gitmodules, you need to either give up on
>
>        (i) bisectability; it's not good enough to restore the canonical
>        .gitmodules contents on merge, since the bisect can run into one
>        of the commits on fred' branchs
>
>        (ii) publishing the exact same branch for testing and merging
>
> But I start to feel that the tradeoff of (ii) is really not so bad at
> alland this would be perhaps the most elegant solution. You can either
>
>        (a) make two parallel branches, one with your .gitmodules and
>        one with the upstream's
>
>        (b) probably better, stick a commit at the top of your branch
>        that will change .gitmodules to your locations; others can
>        check out fred, test things out, then merge fred^; you can even
>        generally go back in fred's commits if you just 'git submodule
>        update' right after checking fred out, since all the required
>        submodule commits will be probably already fetched.
>
> So I say just go for the (ii)-(b) combination. :-)
>

Hmm. Locally modifying my .gitmodules still feels bad because I don't
like either of those tradeoffs (but I don't have any sensible
suggestion yet).

As a bit of background (as to why I'd dislike (a) and (b)), we had a
team switch to git, and one of the really nice things is the ability
to share stuff around and branch freely - but the flipside of that is
that we tend to push to a central repo more rarely, so the advantages
of an continuous integration server become less. What we did is to
tell a centralised CI server the URLs of all the team's git
repositories, and it would periodically pull from them, speculatively
compile anything new, and run the big suite of tests - finishing up by
emailling them a heads-up that a particular state in their repo is
'bad'.

This was really popular as it was demonstrably better than anything we
could do with svn, and best of all, it's pretty much transparent - as
a user you don't have to do anything at all.

I could do it now by hacking about with files; it'd just be nice to
keep it transparent and make it a directly supported feature.

^ permalink raw reply

* Re: [PATCH] Teach git submodule update to use distributed repositories
From: Petr Baudis @ 2008-07-18 14:43 UTC (permalink / raw)
  To: Nigel Magnay; +Cc: Johannes Schindelin, Git Mailing List
In-Reply-To: <320075ff0807180420k4b28c317mc026713b22c44839@mail.gmail.com>

On Fri, Jul 18, 2008 at 12:20:13PM +0100, Nigel Magnay wrote:
> On Fri, Jul 18, 2008 at 11:00 AM, Petr Baudis <pasky@suse.cz> wrote:
> > On Fri, Jul 18, 2008 at 10:36:51AM +0100, Nigel Magnay wrote:
> >> On Fri, Jul 18, 2008 at 10:16 AM, Petr Baudis <pasky@suse.cz> wrote:
> >> > snip
> >> >
> >> >        "How do we mass-supply custom submodule URLs when publishing the
> >> >        customized main repository at a custom location too?"
> >> >
> >> Yes - that is an additional problem.
> >
> > Wait, I'm lost again - _additional_ problem? How does it differ from the
> > _original_ problem, how does it differ from what you're explaining below
> > and how does what you're explaining below differ from the original
> > problem?
> >
> In addition to the problem of needing to execute multiple commands and
> edit files to acheive what is a rather simple usecase, there is the
> additional problem of discovering (for a third party) a url for where
> their submodules are stored.

I see. That's interconnected as a single "How to check Fred's work"
problem for me. :-)

> >> If I may expand the usecase just so it's clear (and to check we're
> >> talkiing the same language)
> >>
> >> I do something like
> >> $ git remote add fred git://fredcomputer/superproject/.git
> >> $ git fetch --submodules fred
> >
> > I think you mean git pull --submodules fred. Well, actually, you want to
> > pull the main repository, then submodule update (_not_ pull in the
> > submodules). See? This is part of the "semantic swamp" I mentioned
> > before.
> 
> Ah - I understand. You're saying "you can't pull submodules when you
> pull the supermodule, because you don't know which submodules might be
> needed until you also merge / checkout the desired revision" ?
> 
> Ack.

That is something I might agree with, but my point is that within the
submodule,

	git pull

simply isn't a sensible operation at all! You don't want to do any
merges or whatever, just bring the submodule to a defined commit id.
So you want to do something significantly different:

	git fetch
	git reset --hard <commitid>

And that's what 'git submodule update' already does.

> Hm. It feels like each person could have some 'local' info in their
> .gitmodules, and rules around merging; but I'm not sure of exactly
> what, or how.

Again, when customizing .gitmodules, you need to either give up on

	(i) bisectability; it's not good enough to restore the canonical
	.gitmodules contents on merge, since the bisect can run into one
	of the commits on fred' branchs

	(ii) publishing the exact same branch for testing and merging

But I start to feel that the tradeoff of (ii) is really not so bad at
alland this would be perhaps the most elegant solution. You can either

	(a) make two parallel branches, one with your .gitmodules and
	one with the upstream's

	(b) probably better, stick a commit at the top of your branch
	that will change .gitmodules to your locations; others can
	check out fred, test things out, then merge fred^; you can even
	generally go back in fred's commits if you just 'git submodule
	update' right after checking fred out, since all the required
	submodule commits will be probably already fetched.

So I say just go for the (ii)-(b) combination. :-)

-- 
				Petr "Pasky" Baudis
As in certain cults it is possible to kill a process if you know
its true name.  -- Ken Thompson and Dennis M. Ritchie

^ permalink raw reply

* Re: Considering teaching plumbing to users harmful
From: J. Bruce Fields @ 2008-07-18 14:35 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Johannes Schindelin, git
In-Reply-To: <7vmykgfhtj.fsf@gitster.siamese.dyndns.org>

On Thu, Jul 17, 2008 at 12:10:00PM -0700, Junio C Hamano wrote:
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > On Thu, 17 Jul 2008, Junio C Hamano wrote:
> >
> >> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> >> 
> >> >> Is there a way to commit the contents of a tarball without using 
> >> >> plumbing?  I occasionally want to track an upstream that I know only 
> >> >> as a series of tarballs, so I do something like:
> >> >> 
> >> >> 	cd repo/
> >> >> 	git checkout upstream
> >> >> 	rm -rf *
> >> >> 	tar -xzvf ../new-version.tar.gz
> >> >
> >> > How about "git add -u" and "git add ."?
> >> 
> >> It would work only if new version never removes files.
> >
> > You made me doubt for a second there.  But "git add -u" updates the index 
> > when a tracked files was deleted.  So after "rm -rf *", "git add -u" would 
> > empty the index.
> 
> I thought everybody would react to my message like so after sending it ;-)
> What I failed to say was that the main uneasiness about the above command
> sequence Bruce or anybody would have felt would be that "rm -fr *" step,
> which in itself look scary and does not remove .frotz that came from older
> version.

Yeah, good point, that's not very careful.

But actually it's "add -u" that I missed--I forgot it would take into
account removed files as well.  Thanks!

--b.

^ permalink raw reply

* [PATCH 1/2] archive: make zip compression level independent from core git
From: René Scharfe @ 2008-07-18 14:30 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git Mailing List

zlib_compression_level is the compression level used for git's object store.
It's 1 by default, which is the fastest setting.  This variable is also used
as the default compression level for ZIP archives created by git archive.

For archives, however, zlib's own default of 6 is more appropriate, as it's
favouring small size over speed -- archive creation is not that performance
critical most of the time.

This patch makes git archive independent from git's internal compression
level setting.  It affects invocations of git archive without explicitly
specified compression level option, only.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
 archive-zip.c     |    9 +++++----
 archive.h         |    1 +
 builtin-archive.c |    3 ++-
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/archive-zip.c b/archive-zip.c
index d56e5cf..fb12398 100644
--- a/archive-zip.c
+++ b/archive-zip.c
@@ -93,7 +93,7 @@ static void copy_le32(unsigned char *dest, unsigned int n)
 }
 
 static void *zlib_deflate(void *data, unsigned long size,
-                          unsigned long *compressed_size)
+		int compression_level, unsigned long *compressed_size)
 {
 	z_stream stream;
 	unsigned long maxsize;
@@ -101,7 +101,7 @@ static void *zlib_deflate(void *data, unsigned long size,
 	int result;
 
 	memset(&stream, 0, sizeof(stream));
-	deflateInit(&stream, zlib_compression_level);
+	deflateInit(&stream, compression_level);
 	maxsize = deflateBound(&stream, size);
 	buffer = xmalloc(maxsize);
 
@@ -157,7 +157,7 @@ static int write_zip_entry(struct archiver_args *args,
 		method = 0;
 		attr2 = S_ISLNK(mode) ? ((mode | 0777) << 16) :
 			(mode & 0111) ? ((mode) << 16) : 0;
-		if (S_ISREG(mode) && zlib_compression_level != 0)
+		if (S_ISREG(mode) && args->compression_level != 0)
 			method = 8;
 		crc = crc32(crc, buffer, size);
 		out = buffer;
@@ -169,7 +169,8 @@ static int write_zip_entry(struct archiver_args *args,
 	}
 
 	if (method == 8) {
-		deflated = zlib_deflate(buffer, size, &compressed_size);
+		deflated = zlib_deflate(buffer, size, args->compression_level,
+				&compressed_size);
 		if (deflated && compressed_size - 6 < size) {
 			/* ZLIB --> raw compressed data (see RFC 1950) */
 			/* CMF and FLG ... */
diff --git a/archive.h b/archive.h
index 96bb1cd..4a02371 100644
--- a/archive.h
+++ b/archive.h
@@ -13,6 +13,7 @@ struct archiver_args {
 	time_t time;
 	const char **pathspec;
 	unsigned int verbose : 1;
+	int compression_level;
 };
 
 typedef int (*write_archive_fn_t)(struct archiver_args *);
diff --git a/builtin-archive.c b/builtin-archive.c
index d5e3af8..cff6ce7 100644
--- a/builtin-archive.c
+++ b/builtin-archive.c
@@ -185,9 +185,10 @@ int parse_archive_args(int argc, const char **argv, const struct archiver **ar,
 	if (!*ar)
 		die("Unknown archive format '%s'", format);
 
+	args->compression_level = Z_DEFAULT_COMPRESSION;
 	if (compression_level != -1) {
 		if ((*ar)->flags & USES_ZLIB_COMPRESSION)
-			zlib_compression_level = compression_level;
+			args->compression_level = compression_level;
 		else {
 			die("Argument not supported for format '%s': -%d",
 					format, compression_level);
-- 
1.5.6.2.212.g08b51

^ permalink raw reply related

* [PATCH 2/2] archive: remove unused headers
From: René Scharfe @ 2008-07-18 14:30 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git Mailing List

Remove obsolete #includes.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
 archive-tar.c     |    2 --
 archive-zip.c     |    5 -----
 builtin-archive.c |    2 --
 3 files changed, 0 insertions(+), 9 deletions(-)

diff --git a/archive-tar.c b/archive-tar.c
index f9eb726..1302961 100644
--- a/archive-tar.c
+++ b/archive-tar.c
@@ -2,9 +2,7 @@
  * Copyright (c) 2005, 2006 Rene Scharfe
  */
 #include "cache.h"
-#include "commit.h"
 #include "tar.h"
-#include "builtin.h"
 #include "archive.h"
 
 #define RECORDSIZE	(512)
diff --git a/archive-zip.c b/archive-zip.c
index fb12398..cf28504 100644
--- a/archive-zip.c
+++ b/archive-zip.c
@@ -2,11 +2,6 @@
  * Copyright (c) 2006 Rene Scharfe
  */
 #include "cache.h"
-#include "commit.h"
-#include "blob.h"
-#include "tree.h"
-#include "quote.h"
-#include "builtin.h"
 #include "archive.h"
 
 static int zip_date;
diff --git a/builtin-archive.c b/builtin-archive.c
index cff6ce7..df97724 100644
--- a/builtin-archive.c
+++ b/builtin-archive.c
@@ -7,10 +7,8 @@
 #include "archive.h"
 #include "commit.h"
 #include "tree-walk.h"
-#include "exec_cmd.h"
 #include "pkt-line.h"
 #include "sideband.h"
-#include "attr.h"
 
 static const char archive_usage[] = \
 "git archive --format=<fmt> [--prefix=<prefix>/] [--verbose] [<extra>] <tree-ish> [path...]";
-- 
1.5.6.2.212.g08b51

^ permalink raw reply related

* [PATCH] Documentation: How to ignore local changes in tracked files
From: Petr Baudis @ 2008-07-18 14:11 UTC (permalink / raw)
  To: gitster; +Cc: git
In-Reply-To: <20080717182619.GG10151@machine.or.cz>

This patch explains more carefully that `.gitignore` concerns only
untracked files and refers the reader to

	git update-index --assume-unchanged

in the need of ignoring uncommitted changes in already tracked files.
The description of this option is lifted to a more "porcelainish"
level and explains the caveats of this usecase.

Whether feasible or not, I believe adding this functionality to
the porcelain is out of the scope of this patch. (And I personally
think that referring to the plumbing in the case of such a special
usage is fine.)

This is currently probably one of the top FAQs at #git and the
--assume-unchanged switch is not widely known; gitignore(5) is the first
place where people are likely to look for it.

Signed-off-by: Petr Baudis <pasky@suse.cz>
---

 Documentation/git-update-index.txt |   10 ++++++++++
 Documentation/gitignore.txt        |   11 ++++++++---
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt
index a91fd21..6b930bc 100644
--- a/Documentation/git-update-index.txt
+++ b/Documentation/git-update-index.txt
@@ -88,6 +88,16 @@ OPTIONS
 	sometimes helpful when working with a big project on a
 	filesystem that has very slow lstat(2) system call
 	(e.g. cifs).
++
+This option can be also used as a coarse file-level mechanism
+to ignore uncommitted changes in tracked files (akin to what
+`.gitignore` does for untracked files).
+You should remember that an explicit 'git add' operation will
+still cause the file to be refreshed from the working tree.
+Git will fail (gracefully) in case it needs to modify this file
+in the index e.g. when merging in a commit;
+thus, in case the assumed-untracked file is changed upstream,
+you will need to handle the situation manually.
 
 -g::
 --again::
diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt
index fc0efd8..59321a2 100644
--- a/Documentation/gitignore.txt
+++ b/Documentation/gitignore.txt
@@ -13,9 +13,14 @@ DESCRIPTION
 -----------
 
 A `gitignore` file specifies intentionally untracked files that
-git should ignore.  Each line in a `gitignore` file specifies a
-pattern.
-
+git should ignore.
+Note that all the `gitignore` files really concern only files
+that are not already tracked by git;
+in order to ignore uncommitted changes in already tracked files,
+please refer to the 'git update-index --assume-unchanged'
+documentation.
+
+Each line in a `gitignore` file specifies a pattern.
 When deciding whether to ignore a path, git normally checks
 `gitignore` patterns from multiple sources, with the following
 order of precedence, from highest to lowest (within one level of

^ permalink raw reply related

* [PATCH] Documentation/git-submodule.txt: Further clarify the description
From: Petr Baudis @ 2008-07-18 13:40 UTC (permalink / raw)
  To: gitster; +Cc: git, Heikki Orsila
In-Reply-To: <20080718133644.GQ10151@machine.or.cz>

This patch rewrites the general description yet again, first clarifying
the high-level concept, mentioning the difference to remotes and using
the subtree merge strategy, then getting to the details about tree
entries and .gitmodules file.

The patch also makes few smallar grammar fixups within the rest of the
description and clarifies how does 'init' relate to 'update --init'.

Cc: Heikki Orsila <shdl@zakalwe.fi>
Signed-off-by: Petr Baudis <pasky@suse.cz>
---

 Documentation/git-submodule.txt |   68 ++++++++++++++++++++++++++-------------
 1 files changed, 46 insertions(+), 22 deletions(-)

diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index bb4e6fb..755142c 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -18,24 +18,43 @@ SYNOPSIS
 
 DESCRIPTION
 -----------
-Submodules are a special kind of tree entries which refer to a particular tree
-state in another repository.  The tree entry describes
-the existence of a submodule with the given name and the exact revision that
-should be used, while an entry in `.gitmodules` file gives the location of
-the repository.
-
-When checked out, submodules will maintain their own independent repositories
-within their directories; the only link between the submodule and the "parent
-project" is the tree entry within the parent project mentioned above.
-
-This command will manage the tree entries and contents of the gitmodules file
-for you, as well as inspecting the status of your submodules and updating them.
-When adding a new submodule to the tree, the 'add' subcommand is to be used.
-However, when pulling a tree containing submodules, these will not be checked
-out by default; the 'init' and 'update' subcommands will maintain submodules
-checked out and at appropriate revision in your working tree. You can inspect
-the current status of your submodules using the 'submodule' subcommand and get
-an overview of changes 'update' would perform using the 'summary' subcommand.
+Submodules allow foreign repositories to be embedded within
+a dedicated subdirectory of the source tree, always pointed
+at a particular commit.
+
+They are not to be confused with remotes, which are meant mainly
+for branches of the same project; submodules are meant for
+different projects you would like to make part of your source tree,
+while the history of the two projects still stays completely
+independent and you cannot modify the contents of the submodule
+from within the main project.
+In case you want to merge the project histories, possibly make
+local modifications within the subtree, and considered the fact
+that all users will have to download and check out the subtree,
+you may choose to add a remote for the other project and use
+the 'subtree' merge strategy instead of setting up a submodule.
+
+Submodules are composed from a so-called `gitlink` tree entry
+in the main repository that refers to a particular commit object
+within the (completely separate) inner repository,
+and a record in the `.gitmodules` file at the root of the source
+tree, assigning a logical name to the submodule and describing
+the default URL the submodule shall be cloned from.
+The logical name can be used for overriding this URL within your
+local repository configuration (see 'submodule init').
+
+This command will manage the tree entries and contents of the
+gitmodules file for you, as well as inspect the status of your
+submodules and update them.
+When adding a new submodule to the tree, the 'add' subcommand
+is to be used.  However, when pulling a tree containing submodules,
+these will not be checked out by default;
+the 'init' and 'update' subcommands will maintain submodules
+checked out and at appropriate revision in your working tree.
+You can briefly inspect the up-to-date status of your submodules
+using the 'status' subcommand and get a detailed overview of the
+difference between the index and checkouts using the 'summary'
+subcommand.
 
 
 COMMANDS
@@ -78,10 +97,15 @@ status::
 	repository. This command is the default command for 'git-submodule'.
 
 init::
-	Initialize the submodules, i.e. register in .git/config each submodule
-	name and url found in .gitmodules. The key used in .git/config is
-	`submodule.$name.url`. This command does not alter existing information
-	in .git/config.
+	Initialize the submodules, i.e. register each submodule name
+	and url found in .gitmodules into .git/config.
+	The key used in .git/config is `submodule.$name.url`.
+	This command does not alter existing information in .git/config.
+	You can then customize the submodule clone URLs in .git/config
+	for your local setup and proceed to 'git submodule update';
+	you can also just use 'git submodule update --init' without
+	the explicit 'init' step if you do not intend to customize
+	any submodule locations.
 
 update::
 	Update the registered submodules, i.e. clone missing submodules and

^ permalink raw reply related

* Re: [PATCH 2/3] add new Git::Repo API
From: Lea Wiemann @ 2008-07-18 13:40 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git, John Hawley, Petr Baudis
In-Reply-To: <200807180149.18565.jnareb@gmail.com>

Jakub Narebski wrote:
> [$commit->author:] We would probably want _in the future_ to  return some
> object wrapper, which stringifies to value of author and committer headers

Yup, good idea.  They'll even stay strings, they'll just be blessed.

>>>> +=item $commit->message
> 
> I'd rather then have _git_ convert it to UTF=8 for us (using 
> --encoding=<encoding> option to git-log/git-rev-list)

Yeah, I guess the API should actually decode it.  You wouldn't want to
have the message in UTF-8 but in Unicode (I suggest you read man
perlunitut if you haven't done so).  We cannot have git do the decoding,
since (apart from the fact that it doesn't smell right) it isn't
guaranteed to emit valid UTF-8 (thanks Junio for the pointer):

Lea Wiemann: Does anyone know off the top of their heads how git handles
    character decoding errors in commands like git log? [...]
Junio 'gitster' Hamano: silently punt and show the original unmolested.
Junio 'gitster' Hamano: cf. pretty.c:pretty_print_commit()

So we're not guaranteed to be able to, in turn, decode git's output into
actual characters since it might just be byte soup.

Hence, how about this fallback strategy:

1. Decode according to the encoding header.
2. Decode as UTF-8 (passing through byte soup is often equivalent to
decoding UTF-8 since many terminals use UTF-8, and trying UTF-8 is
reasonably safe).
3. Decode as Latin1.

(Not that the fallbacks will matter a lot in practice, I think.)

> It is (much) better than forking git-cat-file for each commit shown
> on the list; nevertheless I think that it would be better to use git-log
> to generate list (or Git::Revlist) of Git::Commit objects.  It is one
> fork less, but what more important you don't have to access repository
> twice for the very same objects.

You're confused; it's not one fork less, it's a write to a pipe less.
(Pleeeease look at the code before you write something.  It's there, in
this very thread.)  And I don't believe the "access the repository
twice" thing is anywhere near an actual issue.  To summarize, you're
asking me to (a) write code and (presumably) (b) add something to the
interface of a public API, based on some (most probably faulty)
assumptions about performance?  You should really read
<http://c2.com/cgi/wiki?PrematureOptimization>.

> if I understand correctly for log-like views you 
> propose to first run simple git-rev-list [...], then feed list of
> revisions (perhaps via cache, i.e. excluding objects which are in
> cache) to 'git cat-file --batch' open two-directional pipeline.

Yup, it's an option, though currently it's a single cached call to git
log (or git rev-list).

> What I propose instead is to provide alternate method to fully 
> instantiate Git::Commit object (in addition to ->_load), which would 
> fill fields by parsing git-log / git-rev-list --headers output

Yes, but this would need a method in the API, it's not an optimization
that falls out for free.  Cluttering an API for some obscure (= very
doubtful) optimization?  Bad Idea.(tm)

> "git cat-file --batch" should have commits to be
> accessed in filesystem cache, which means in memory; but it is possible
> that they wouldn't be in cache because of I/O pressure

No.  Page cache turnover time is at least around 10 seconds (and that's
under fairly artificial conditions), definitely not in the millisecond
range.

> I think that _not using_ Git::Cmd (or somesuch) API results in botched,
> horrible API
>   our $git_version = $repo_root->repo(directory => 'dummy')->version;
> (Unless it is not needed any longer, or not used any longer; if it is
> so, then perhaps implementing Git::Cmd as generic wrapper around git
> commands, hiding for example ActivePerl hack, could be left for later).

It isn't used any longer -- I really suggest you read the whole thread
before replying. ;-)

>> As I wrote in my reply to Petr [...]
> 
> Just a question: was this reply only to him, or to all?

To all, otherwise I wouldn't have Cc'ed the list.

>> I wouldn't -- see my blurb about error handling at the top of my reply
>> to Petr (<487BD0F3.2060508@gmail.com>).  You're not supposed to pass
>> anything that you didn't get from get_sha1 into Git::Commit or
>> Git::Tag constructors, or your error handling is invariably broken.
> 
> I can understand this simpler, although less than optimal, and geared
> mainly towards gitweb needs.

FTR, yes it is simpler, but no, it is not really geared toward gitweb
needs, and it's definitely not "less than optimal" in the sense of being
worse than the exception-based error handling Git.pm does.  Trust on me
on this one. ;-)

> Errr... "yes" to first question means that 'reuse' option makes sense
> _only_ for get_bidi_pipe? If so, why it is present in other commands?

Yes, and no, it isn't present in other commands.  (Hey, could you please
check the code before posting?  Really.)

>>> Why name_rev, and no describe?
>> Feel free to add it. ;-)  (It might take some work to come up with a
>> decent interface for that method.)
> 
> Why do you _need_ name_rev, if you are not to include git-describe
> equivalent.

I needed it for gitweb.  As I said, I'm not trying to create a complete
API.  A describe_rev (or so) method can be added later, if and when it's
needed.  (As I said, I don't think writing APIs without at least one use
case is a good idea anyway.)

>>> Should (for completeness) Git::Tag provide $tag->validate() method?
> 
> I meant here equivalent of "git tag -v <tag>"

I guess it could be added.  As with describe_rev, I won't add it myself,
in particular not as part of this patch series.

-- Lea

^ permalink raw reply

* Re: [PATCH] Documentation/git-submodule.txt: Further clarify the description
From: Petr Baudis @ 2008-07-18 13:36 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Heikki Orsila
In-Reply-To: <7v4p6ofedl.fsf@gitster.siamese.dyndns.org>

On Thu, Jul 17, 2008 at 01:24:22PM -0700, Junio C Hamano wrote:
> Your lines are getting overlong to be easily quoted and commented...

I will watch for that.

> Petr Baudis <pasky@suse.cz> writes:
> > +....  In case you want to merge the project
> > +histories, possibly make local modifications within the tree, but also do not
> > +mind that your repository will bulk up with all the contents of the other
> > +project, consider adding a remote for the other project and using the 'subtree'
> > +merge strategy instead of setting up a submodule.
> 
> I'd suggest rephrasing "do not mind" to something a lot less nagative.
> The user decides to merge because both histories *are* relevant and at
> that point there is no _minding_ anymore.  If you want to have them, you
> not only "do not mind to have" them but you positively "want" them.
> 
> On the other hand, a situation where you would want to use submodules is
> when not necessarily all users of the superproject would want to have all
> submodules cloned nor checked out.  This needs to be stressed with equal
> weight as the above sentence in this "contrasting merged histories and
> submodules" paragraph.  With that explained clearly upfront, it would
> become easier for the readers to understand why you can choose not to even
> update nor fetch submodules you are not interested in.

You are right. I have tried to reword the sentence to fix these issues.

> > +Submodules are composed from a special kind of tree entry (so-called `gitlink`)
> > +in the main repository that refers to a particular commit object within
> 
> Do we have to say "special"?  Is a gitlink any more special than blob and
> tree entries are?  It tends to be rarer, it came later, but I do not think
> there is anything special from the end user's point of view.

Also the parenthesis look ugly, so I have reworded this to a simpler
formulation.

> >  checked out and at appropriate revision in your working tree. You can inspect
> >  the current status of your submodules using the 'submodule' subcommand and get
> > +an overview of the changes 'update' would perform using the 'summary'
> > +subcommand.
> 
> Sorry, cannot parse the last three lines...

The mention of 'update' is confusing, and it was overally imprecise.
(I think that in general, the summary/status distinction was not a wise
UI decision.)

-- 
				Petr "Pasky" Baudis
As in certain cults it is possible to kill a process if you know
its true name.  -- Ken Thompson and Dennis M. Ritchie

^ permalink raw reply

* [PATCH] Documentation/git-merge.txt: Partial rewrite of How Merge Works
From: Petr Baudis @ 2008-07-18 13:20 UTC (permalink / raw)
  To: gitster; +Cc: git
In-Reply-To: <20080718131800.GP10151@machine.or.cz>

The git-merge documentation's "HOW MERGE WORKS" section is confusingly
composed and actually omits the most interesting part, the merging of
the arguments into HEAD itself, surprisingly not actually mentioning
the fast-forward merge anywhere.

This patch replaces the "[NOTE]" screenful of highly technical details
by a single sentence summing up the interesting information, and instead
explains how are the arguments compared with HEAD and the three possible
inclusion states that are named "Already up-to-date", "Fast-forward"
and "True merge". It also makes it clear that the rest of the section
talks only about the true merge situation.

Junio initiated the removal of the Note screenful altogether and
offered many stylistical fixes.

Signed-off-by: Petr Baudis <pasky@suse.cz>
---

 Documentation/git-merge.txt |   69 ++++++++++++++++---------------------------
 1 files changed, 25 insertions(+), 44 deletions(-)

diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt
index 019e4ca..77c62aa 100644
--- a/Documentation/git-merge.txt
+++ b/Documentation/git-merge.txt
@@ -57,50 +57,31 @@ HOW MERGE WORKS
 
 A merge is always between the current `HEAD` and one or more
 commits (usually, branch head or tag), and the index file must
-exactly match the
-tree of `HEAD` commit (i.e. the contents of the last commit) when
-it happens.  In other words, `git diff --cached HEAD` must
-report no changes.
-
-[NOTE]
-This is a bit of a lie.  In certain special cases, your index is
-allowed to be different from the tree of the `HEAD` commit.  The most
-notable case is when your `HEAD` commit is already ahead of what
-is being merged, in which case your index can have arbitrary
-differences from your `HEAD` commit.  Also, your index entries
-may have differences from your `HEAD` commit that match
-the result of a trivial merge (e.g. you received the same patch
-from an external source to produce the same result as what you are
-merging).  For example, if a path did not exist in the common
-ancestor and your head commit but exists in the tree you are
-merging into your repository, and if you already happen to have
-that path exactly in your index, the merge does not have to
-fail.
-
-Otherwise, merge will refuse to do any harm to your repository
-(that is, it may fetch the objects from remote, and it may even
-update the local branch used to keep track of the remote branch
-with `git pull remote rbranch:lbranch`, but your working tree,
-`.git/HEAD` pointer and index file are left intact).  In addition,
-merge always sets `.git/ORIG_HEAD` to the original state of HEAD so
-a problematic merge can be removed by using `git reset ORIG_HEAD`.
-
-You may have local modifications in the working tree files.  In
-other words, 'git-diff' is allowed to report changes.
-However, the merge uses your working tree as the working area,
-and in order to prevent the merge operation from losing such
-changes, it makes sure that they do not interfere with the
-merge. Those complex tables in read-tree documentation define
-what it means for a path to "interfere with the merge".  And if
-your local modifications interfere with the merge, again, it
-stops before touching anything.
-
-So in the above two "failed merge" case, you do not have to
-worry about loss of data --- you simply were not ready to do
-a merge, so no merge happened at all.  You may want to finish
-whatever you were in the middle of doing, and retry the same
-pull after you are done and ready.
-
+match the tree of `HEAD` commit (i.e. the contents of the last commit)
+when it starts out.  In other words, `git diff --cached HEAD` must
+report no changes.  (One exception is when the changed index
+entries are already in the same state that would result from
+the merge anyway.)
+
+Three kinds of merge can happen:
+
+* The merged commit is already contained in `HEAD`. This is the
+  simplest case, called "Already up-to-date."
+
+* `HEAD` is already contained in the merged commit. This is the
+  most common case especially when involved through 'git pull':
+  you are tracking an upstream repository, committed no local
+  changes and now you want to update to a newer upstream revision.
+  Your `HEAD` (and the index) is updated to at point the merged
+  commit, without creating an extra merge commit.  This is
+  called "Fast-forward".
+
+* Both the merged commit and `HEAD` are independent and must be
+  tied together by a merge commit that has them both as its parents.
+  The rest of this section describes this "True merge" case.
+
+The chosen merge strategy merges the two commits into a single
+new source tree.
 When things cleanly merge, these things happen:
 
 1. The results are updated both in the index file and in your

^ permalink raw reply related

* Re: [PATCH] Documentation/git-merge.txt: Expand the How Merge Works   section
From: Petr Baudis @ 2008-07-18 13:18 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vd4lcfgoo.fsf@gitster.siamese.dyndns.org>

  Hi,

On Thu, Jul 17, 2008 at 12:34:31PM -0700, Junio C Hamano wrote:
> Petr Baudis <pasky@suse.cz> writes:
> 
> >   I'm not sure if I should resend the updated patch, or if you already
> > included your comments yourself.
> 
> When I send my review comments out, I generally expect an updated version,
> unless I explicitly say "will apply with tweaks, no need to resend".

  ok, that is pretty much what I expected, I just wanted to avoid doing
duplicate work. :-)

..snip..
> yes, I am strongly hinting to drop that description; it
> is not even remotely interesting

  I have tried to salvage the now-subsection for a while yet, but
ultimately, I now feel as well that it is not worth it; the meat of it
can be summed up in a single sentence that I have re-added to the main
section.

> However, I think we may want to talk about "How to tell if your merge did
> not even touch your index nor working tree" somewhere in the manual.
> "When there are conflicts, these things happen" part talks about how to
> resolve conflicts, but when merge refuses to avoid losing local changes,
> the instruction in that part does not apply.

  I'm not sure if this is worth pondering about? The action would feel
rather obvious to me - get rid of the local changes somehow, either
committing them or stashing them or wiping them out. Is that worth
elaborating, or is there more to it?

-- 
				Petr "Pasky" Baudis
GNU, n. An animal of South Africa, which in its domesticated state
resembles a horse, a buffalo and a stag. In its wild condition it is
something like a thunderbolt, an earthquake and a cyclone. -- A. Pierce

^ permalink raw reply

* sparse checkout UI
From: Nguyen Thai Ngoc Duy @ 2008-07-18 13:03 UTC (permalink / raw)
  To: Git Mailing List

Hi,

I gave up on subtree checkout, the cvs/svn way (making subtree
toplevel worktree). Instead I have been working on sparse checkout,
which better fits Git's "working at toplevel worktree" philosophy.
Things are shaping up, but I still have not figured out UI for
entering/leaving/updating sparse checkout.

Should it be an option for git-checkout, like "git checkout
--sparse=git-gui"? Or making it a separate command? git-clone may need
"--sparse-checkout" option anyway, to be able to do sparse checkout
from the beginning.

Opinions?
-- 
Duy

^ permalink raw reply

* [PATCH v2] editor.c: Libify launch_editor()
From: Stephan Beyer @ 2008-07-18 12:35 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git, Stephan Beyer
In-Reply-To: <alpine.DEB.1.00.0807181405510.3932@eeepc-johanness>

This patch removes exit()/die() calls and builtin-specific messages
from launch_editor(), so that it can be used as a general libgit.a
function to launch an editor.

Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
---

Hi,

Johannes Schindelin wrote:
> On Fri, 18 Jul 2008, Stephan Beyer wrote:
> 
> > This patch removes exit()/die() calls and builtin-specific messages from 
> > launch_editor(), so that it can be used as a general libgit.a function 
> > to launch an editor.
> 
> Thanks.  Now we have to convince Junio that it is a good idea :-)
> 
> > diff --git a/builtin-commit.c b/builtin-commit.c
> > index ed3fe3f..64f69f3 100644
> > --- a/builtin-commit.c
> > +++ b/builtin-commit.c
> > @@ -647,7 +647,9 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
> >  		char index[PATH_MAX];
> >  		const char *env[2] = { index, NULL };
> >  		snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
> > -		launch_editor(git_path(commit_editmsg), NULL, env);
> > +		if (launch_editor(git_path(commit_editmsg), NULL, env))
> > +			die("running editor failed.\n"
> > +			"Please supply the message using either -m or -F option.");
> 
> In the error case, run_editor() already said more than "running editor 
> failed.", right?  Maybe you just want to skip that line and keep the 
> second?

Well, I wanted to do it like that, but die_builtin() usually adds "fatal: ",
so the message becomes like:

	error: There was a problem with the editor xxx.
	fatal: Please supply the message using either -m or -F option.
        ^^^^^^^^^^^^^
        That looks odd.

Btw, using the former patch, it is:

	error: There was a problem with the editor xxx.
	fatal: running editor failed.
	Please supply the message using either -m or -F option.


So I wonder if I should not die() at all, but do a
	fprintf(stderr, "Please supply the message using either -m or -F option.\n");
	exit(1);
which is done in *this* version of the patch. So that the message becomes:

	error: There was a problem with the editor 'xxx'.
	Please supply the message using either -m or -F option.

> > diff --git a/editor.c b/editor.c
> > index 483b62d..5d7f5f9 100644
> > --- a/editor.c
> > +++ b/editor.c
> > @@ -17,9 +17,8 @@ void launch_editor(const char *path, struct strbuf *buffer, const char *const *e
> >  	terminal = getenv("TERM");
> >  	if (!editor && (!terminal || !strcmp(terminal, "dumb"))) {
> >  		fprintf(stderr,
> > -		"Terminal is dumb but no VISUAL nor EDITOR defined.\n"
> > -		"Please supply the message using either -m or -F option.\n");
> > -		exit(1);
> > +		"Terminal is dumb but no VISUAL nor EDITOR defined.\n");
> > +		return 1;
> 
> Why not "return error()"?

I was unsure here, too, but you're right.

Regards.

 builtin-commit.c |    6 +++++-
 builtin-tag.c    |    6 +++++-
 editor.c         |   24 ++++++++++++------------
 foo              |    1 +
 strbuf.h         |    2 +-
 5 files changed, 24 insertions(+), 15 deletions(-)
 create mode 100644 foo

diff --git a/builtin-commit.c b/builtin-commit.c
index ed3fe3f..23ec629 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -647,7 +647,11 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
 		char index[PATH_MAX];
 		const char *env[2] = { index, NULL };
 		snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
-		launch_editor(git_path(commit_editmsg), NULL, env);
+		if (launch_editor(git_path(commit_editmsg), NULL, env)) {
+			fprintf(stderr,
+			"Please supply the message using either -m or -F option.\n");
+			exit(1);
+		}
 	}
 
 	if (!no_verify &&
diff --git a/builtin-tag.c b/builtin-tag.c
index 219f51d..325b1b2 100644
--- a/builtin-tag.c
+++ b/builtin-tag.c
@@ -295,7 +295,11 @@ static void create_tag(const unsigned char *object, const char *tag,
 			write_or_die(fd, tag_template, strlen(tag_template));
 		close(fd);
 
-		launch_editor(path, buf, NULL);
+		if (launch_editor(path, buf, NULL)) {
+			fprintf(stderr,
+			"Please supply the message using either -m or -F option.\n");
+			exit(1);
+		}
 
 		unlink(path);
 		free(path);
diff --git a/editor.c b/editor.c
index 483b62d..eebc3e9 100644
--- a/editor.c
+++ b/editor.c
@@ -2,7 +2,7 @@
 #include "strbuf.h"
 #include "run-command.h"
 
-void launch_editor(const char *path, struct strbuf *buffer, const char *const *env)
+int launch_editor(const char *path, struct strbuf *buffer, const char *const *env)
 {
 	const char *editor, *terminal;
 
@@ -15,12 +15,8 @@ void launch_editor(const char *path, struct strbuf *buffer, const char *const *e
 		editor = getenv("EDITOR");
 
 	terminal = getenv("TERM");
-	if (!editor && (!terminal || !strcmp(terminal, "dumb"))) {
-		fprintf(stderr,
-		"Terminal is dumb but no VISUAL nor EDITOR defined.\n"
-		"Please supply the message using either -m or -F option.\n");
-		exit(1);
-	}
+	if (!editor && (!terminal || !strcmp(terminal, "dumb")))
+		return error("Terminal is dumb but no VISUAL nor EDITOR defined.");
 
 	if (!editor)
 		editor = "vi";
@@ -28,6 +24,7 @@ void launch_editor(const char *path, struct strbuf *buffer, const char *const *e
 	if (strcmp(editor, ":")) {
 		size_t len = strlen(editor);
 		int i = 0;
+		int failed;
 		const char *args[6];
 		struct strbuf arg0;
 
@@ -43,14 +40,17 @@ void launch_editor(const char *path, struct strbuf *buffer, const char *const *e
 		args[i++] = path;
 		args[i] = NULL;
 
-		if (run_command_v_opt_cd_env(args, 0, NULL, env))
-			die("There was a problem with the editor %s.", editor);
+		failed = run_command_v_opt_cd_env(args, 0, NULL, env);
 		strbuf_release(&arg0);
+		if (failed)
+			return error("There was a problem with the editor '%s'.",
+					editor);
 	}
 
 	if (!buffer)
-		return;
+		return 0;
 	if (strbuf_read_file(buffer, path, 0) < 0)
-		die("could not read message file '%s': %s",
-		    path, strerror(errno));
+		return error("could not read file '%s': %s",
+				path, strerror(errno));
+	return 0;
 }
diff --git a/foo b/foo
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/foo
@@ -0,0 +1 @@
+
diff --git a/strbuf.h b/strbuf.h
index 0c6ffad..eba7ba4 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -123,6 +123,6 @@ extern int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint);
 extern int strbuf_getline(struct strbuf *, FILE *, int);
 
 extern void stripspace(struct strbuf *buf, int skip_comments);
-extern void launch_editor(const char *path, struct strbuf *buffer, const char *const *env);
+extern int launch_editor(const char *path, struct strbuf *buffer, const char *const *env);
 
 #endif /* STRBUF_H */
-- 
1.5.6.3.390.g7b30

^ permalink raw reply related

* Re: [PATCH] editor.c: Libify launch_editor()
From: Johannes Schindelin @ 2008-07-18 12:07 UTC (permalink / raw)
  To: Stephan Beyer; +Cc: git
In-Reply-To: <1216380408-21671-1-git-send-email-s-beyer@gmx.net>

Hi,

On Fri, 18 Jul 2008, Stephan Beyer wrote:

> This patch removes exit()/die() calls and builtin-specific messages from 
> launch_editor(), so that it can be used as a general libgit.a function 
> to launch an editor.

Thanks.  Now we have to convince Junio that it is a good idea :-)

> diff --git a/builtin-commit.c b/builtin-commit.c
> index ed3fe3f..64f69f3 100644
> --- a/builtin-commit.c
> +++ b/builtin-commit.c
> @@ -647,7 +647,9 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
>  		char index[PATH_MAX];
>  		const char *env[2] = { index, NULL };
>  		snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
> -		launch_editor(git_path(commit_editmsg), NULL, env);
> +		if (launch_editor(git_path(commit_editmsg), NULL, env))
> +			die("running editor failed.\n"
> +			"Please supply the message using either -m or -F option.");

In the error case, run_editor() already said more than "running editor 
failed.", right?  Maybe you just want to skip that line and keep the 
second?

> diff --git a/editor.c b/editor.c
> index 483b62d..5d7f5f9 100644
> --- a/editor.c
> +++ b/editor.c
> @@ -17,9 +17,8 @@ void launch_editor(const char *path, struct strbuf *buffer, const char *const *e
>  	terminal = getenv("TERM");
>  	if (!editor && (!terminal || !strcmp(terminal, "dumb"))) {
>  		fprintf(stderr,
> -		"Terminal is dumb but no VISUAL nor EDITOR defined.\n"
> -		"Please supply the message using either -m or -F option.\n");
> -		exit(1);
> +		"Terminal is dumb but no VISUAL nor EDITOR defined.\n");
> +		return 1;

Why not "return error()"?

Rest looks obviously correct to me!

Thanks,
Dscho

^ permalink raw reply

* Re: What's cooking in git.git (topics)
From: Johannes Schindelin @ 2008-07-18 11:56 UTC (permalink / raw)
  To: Nanako Shiraishi; +Cc: Junio C Hamano, git
In-Reply-To: <20080718175040.6117@nanako3.lavabit.com>

Hi,

On Fri, 18 Jul 2008, Nanako Shiraishi wrote:

> Quoting Junio C Hamano <gitster@pobox.com>:
> 
> > * xx/merge-in-c-into-next (Wed Jul 9 13:51:46 2008 -0700) 4 commits
> >  + Teach git-merge -X<option> again.
> >  + Merge branch 'jc/merge-theirs' into xx/merge-in-c-into-next
> >  + builtin-merge.c: use parse_options_step() "incremental parsing"
> >    machinery
> >  + Merge branch 'ph/parseopt-step-blame' into xx/merge-in-c-into-next
> >
> > This needs to be merged to master iff/when merge-theirs gets merged, 
> > but I do not think this series is widely supported, so both are on 
> > hold.
> 
> Why do you say it is not widely supported?  I may be wrong but I think 
> you developed these patches after somebody from the mailing list asked 
> for this feature.

Asking for a feature, and then not doing a single thing to defend why it 
makes sense, of a single person, who does not even speak up now, does not 
count for "wide support".

Ciao,
Dscho

^ permalink raw reply

* Re: What's cooking in git.git (topics)
From: Johannes Schindelin @ 2008-07-18 11:55 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Nanako Shiraishi, git
In-Reply-To: <7v63r38r4r.fsf@gitster.siamese.dyndns.org>

Hi,

On Fri, 18 Jul 2008, Junio C Hamano wrote:

> +The 'recursive' strategy can take the following options:
> +
> +ours;;

You still have not addressed the issue that you can specify multiple 
strategies, or even a single _wrong_ one.  So:

	$ git merge -s stupid -Xours

would not fail at all, but definitely not do the right thing either (it 
disobeys a direct command of the user).

Apart from having to choose different -X option names for the different 
backends, to avoid them from clashing when you specify multiple 
strategies, you also deprive the user from being able to try the _same_ 
backend with different options.

IOW all my objections to the -X option (even that it does not fit with our 
short option parsing paradigm) still apply.

We already have the "-S" wart, let's not add to that pile.

Ciao,
Dscho

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox