Git development
 help / color / mirror / Atom feed
* Re: A Basic Git Question About File Tracking
From: Jon Forrest @ 2011-10-09  0:08 UTC (permalink / raw)
  To: git
In-Reply-To: <20111004012244.GB13836@elie>

On 10/3/2011 6:22 PM, Jonathan Nieder wrote:

[I'm just getting back to this question. I had accidentally
sent this follow up directly to Jonathan but I want to
continue this on the email list.]

> Yes, "x" is tracked.  Moreover, "x" is in the index.  You can
> list files in the index with the "git ls-files -s" command.

This spoils my understanding of what the index
is. I had been thinking that after you add files
to the index, and then commit, the index is then
empty. In other words, whatever's in the index
gets committed, and then the index is cleaned.

On the other hand, if the definition of a tracked
file is a file that's in the index, then this definitely
clears up my understanding of tracked files.

If every file that's 'git add'ed stays in the
index, how does git know which files to commit?

I can't prove it but I suspect that many git beginners
also are confused by this.

Thanks for your replies.

Jon Forrest

^ permalink raw reply

* Re: A Basic Git Question About File Tracking
From: Jakub Narebski @ 2011-10-09  1:17 UTC (permalink / raw)
  To: Jon Forrest; +Cc: git, Jonathan Nieder
In-Reply-To: <4E90E60C.7060105@gmail.com>

Jon Forrest <nobozo@gmail.com> writes:

> On 10/3/2011 6:22 PM, Jonathan Nieder wrote:
> 
> [I'm just getting back to this question. I had accidentally
> sent this follow up directly to Jonathan but I want to
> continue this on the email list.]
> 
> > Yes, "x" is tracked.  Moreover, "x" is in the index.  You can
> > list files in the index with the "git ls-files -s" command.
> 
> This spoils my understanding of what the index
> is. I had been thinking that after you add files
> to the index, and then commit, the index is then
> empty. In other words, whatever's in the index
> gets committed, and then the index is cleaned.
> 
> On the other hand, if the definition of a tracked
> file is a file that's in the index, then this definitely
> clears up my understanding of tracked files.
> 
> If every file that's 'git add'ed stays in the
> index, how does git know which files to commit?
> 
> I can't prove it but I suspect that many git beginners
> also are confused by this.

You seem to be under [false] impression that git commit is about
_changes_ / _changeset_.

It is not true.  What is stored in git commit object is (pointer to)
_snapshot_ of a state of a project at given time.  This means that
"git commit" creates a tree object out of state of the index, and
creates commit object that points to said newly created tree, and has
version you started work from as its parent.  It is commit remember
the previous version that allows to turn commit into changeset.

Hopefully that would clear up your confusion.
-- 
Jakub Narębski

^ permalink raw reply

* Re: [PATCH 6/6] revert: Simplify passing command-line arguments around
From: Tay Ray Chuan @ 2011-10-09  2:14 UTC (permalink / raw)
  To: Ramkumar Ramachandra
  Cc: Git List, Jonathan Nieder, Junio C Hamano, Jeff King,
	Daniel Barkalow, Christian Couder
In-Reply-To: <1318095407-26429-7-git-send-email-artagnon@gmail.com>

On Sun, Oct 9, 2011 at 1:36 AM, Ramkumar Ramachandra <artagnon@gmail.com> wrote:
> [snip]
> [rr: minor improvements, commit message]

This "[]" could go below, under the 3-dash (but before the stat):

> [snip]
> ---
>  builtin/revert.c |   53 +++++++++++++++++++++++++++++------------------------
>  1 files changed, 29 insertions(+), 24 deletions(-)

-- 
Cheers,
Ray Chuan

^ permalink raw reply

* Re: A Basic Git Question About File Tracking [ANSWERED]
From: Jon Forrest @ 2011-10-09  2:42 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <m3ipnz0xri.fsf@localhost.localdomain>

On 10/8/2011 6:17 PM, Jakub Narebski wrote:

> You seem to be under [false] impression that git commit is about
> _changes_ / _changeset_.

This is correct. The Pro Git book says:

"You stage these modified files and then commit
all your staged changes"

Plus, even "git status" tells me

$ git status
# On branch master
# Changes to be committed:

But I see my error. Below is what I hope is a clear
explanation of what I didn't understand. It presumes
that the reader understands the git objects model.
Please let me know if anything is incorrect.
----------
When you "git add" a file two things happen:

1) The file is copied to the git objects tree.
This location where the file is copied depends
on the hash of the file's content.

2) An entry for the file is added to the git index.
This entry includes the same hash that was mentioned
in #1.

A tracked file has an entry in the git index file.
A copy of the file also exists in the objects tree.

When you run 'git status', git computes the hash of
every file in your working directory and looks
up each file in the index. If the file isn't found
then the file is shown as untracked.

When you do a commit, the hash values of everything
in the index are copied into a tree object. The hash
value of the tree object is then placed in a commit object.
No copies of tracked files in the working directory are
made at commit time. This is because the files were already
copied into the objects tree when 'git add' was run.
This is one reason why git commits are so fast.

-----

How's that?

Thanks to everyone for sticking with me on this.

Jon

^ permalink raw reply

* Re: Recovering Committed Changes in a Detached Head?
From: Joel C. Salomon @ 2011-10-09  3:32 UTC (permalink / raw)
  To: git; +Cc: mfick, szeder, daly.gutierrez
In-Reply-To: <ab706826-75df-4410-941e-6b40ec92713c@email.android.com>

On 10/08/2011 06:00 PM, Martin Fick wrote:
>> git reflog to the rescue.
<snip>
>> There you see the first line of the commit message from your "lost"
>> commit, and you can do
>>
>>  git checkout -b lost_detached_head 92aa5381
>>
>> and you get a branch pointing to that commit you made while on
>> detached head, and you can work with it as usual.
> 
> While rflog is cool, I can't help but think that git could be even more helpful for these scenarios.
> 
> First, maybe git could create refs for these automatically, perhaps with a name like orphans/1?  Maybe these refs would only be visible via git branch --orphans.

Creating these "orphan" refs would require the equivalent of (part of)
git-fsck; I can't imagine that could be imposed without significant
overhead on too many operations.  I think you'd be better off wrapping
git-fsck in a script that can create these branches.

--Joel

^ permalink raw reply

* Re: Recovering Committed Changes in a Detached Head?
From: Martin Fick @ 2011-10-09  5:39 UTC (permalink / raw)
  To: Joel C. Salomon, git; +Cc: szeder, daly.gutierrez
In-Reply-To: <4E9115B0.3030701@gmail.com>



"Joel C. Salomon" <joelcsalomon@gmail.com> wrote:

>On 10/08/2011 06:00 PM, Martin Fick wrote:
>>> git reflog to the rescue.
><snip>
>>> There you see the first line of the commit message from your "lost"
>>> commit, and you can do
>>>
>>>  git checkout -b lost_detached_head 92aa5381
>>>
>>> and you get a branch pointing to that commit you made while on
>>> detached head, and you can work with it as usual.
>> 
>> While rflog is cool, I can't help but think that git could be even
>more helpful for these scenarios.
>> 
>> First, maybe git could create refs for these automatically, perhaps
>with a name like orphans/1?  Maybe these refs would only be visible via
>git branch --orphans.
>
>Creating these "orphan" refs would require the equivalent of (part of)
>git-fsck; I can't imagine that could be imposed without significant
>overhead on too many operations.  I think you'd be better off wrapping
>git-fsck in a script that can create these branches.
 
Is there another way to create orphan refs than by doing a checkout and leaving the orphan behind?  I guess a rebase or other branch rewinding operations, but shouldn't it already know on those that that if it alters anything, it will create an orphan?  Git already checks for to see if it is leaving orphan refs behind on a checkout, why not just give the orphan a branch name at those points (not sure what to do if the check is bypassed with -q, just punt I guess)? 

-Martin 


Employee of Qualcomm Innovation Center,Inc. which is a member of Code Aurora Forum

^ permalink raw reply

* Re: Git is not scalable with too many refs/*
From: Michael Haggerty @ 2011-10-09  5:43 UTC (permalink / raw)
  To: Martin Fick
  Cc: git, Christian Couder, Thomas Rast, René Scharfe,
	Julian Phillips
In-Reply-To: <201110081459.52174.mfick@codeaurora.org>

[-- Attachment #1: Type: text/plain, Size: 2441 bytes --]

On 10/08/2011 10:59 PM, Martin Fick wrote:
> [...]
> So, with this in mind, I have discovered, that the fetch 
> performance degradation by invalidating the caches in 
> write_ref_sha1() is actually due to the packed-refs being 
> reloaded and resorted again on each ref insertion (not the 
> loose refs)!!!

Good point.

> I think that all of this might explain why no matter how 
> good Michael's intentions are with his patch series, his 
> series isn't likely to fix this problem

I never claimed that my patch fixes all use cases, or cures cancer
either :-)  One step at a time.

>                                         unless he does not
> invalidate the packed-refs after each insertion.  I tried 
> preventing this invalidation in his series to prove this, 
> but unfortunately, it appears that in his series it is no 
> longer possible to only invalidate just the packed-refs? :(
> Michael, I hope I am completely wrong about that...

Yes, you are completely wrong.  I just implemented more selective cache
invalidation on top of the patch series.

I think your suggestion is safe because only non-symbolic references can
be stored in the packed refs; therefore the modification of a loose ref
can never affect the value of a packed ref.  Of course a loose ref can
*hide* the value of a packed ref, but in such cases the packed ref is
never read anyway.  And the *deletion* of a loose ref can expose a
previously-hidden packed ref, but this case is handled by delete_ref(),
which explicitly invalidates the packed-ref cache.

While I was at it, I also:

* In delete_ref(), only invalidate the packed reference cache if the
reference that is being deleted actually *is* among the packed references.

* Changed the code to stop invalidating the ref caches for submodules.
In the code paths where the cache invalidation was being done, only
main-module references were being changed.  However, I'm not familiar
enough with submodules to know if/when submodule references *can* be
changed.  It could be that the submodule reference caches have to be
invalidated under some circumstances; the current code might be buggy in
this area.

The changes are pushed to github.  They don't make any significant
difference to my "refperf" results (attached), so perhaps a new
benchmark should be added.  But I'm curious to see how they affect your
timings.

Michael

-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/

[-- Attachment #2: refperf-summary.out --]
[-- Type: text/plain, Size: 5251 bytes --]

===================================  =======  =======  =======  =======  =======  =======  =======  =======  =======  =======
Test name                                [0]      [1]      [2]      [3]      [4]      [5]      [6]      [7]      [8]      [9]
===================================  =======  =======  =======  =======  =======  =======  =======  =======  =======  =======
branch-loose-cold                       3.19     3.15     3.10     3.19     3.25     0.70     0.61     0.74     0.66     0.56
branch-loose-warm                       0.19     0.19     0.20     0.19     0.19     0.00     0.00     0.00     0.00     0.00
for-each-ref-loose-cold                 3.73     3.45     3.55     3.39     3.44     3.40     3.50     3.52     3.70     3.51
for-each-ref-loose-warm                 0.44     0.44     0.44     0.43     0.43     0.43     0.43     0.43     0.43     0.43
checkout-loose-cold                     3.35     3.23     3.23     3.15     3.29     0.65     0.71     0.76     0.66     0.69
checkout-loose-warm                     0.19     0.19     0.20     0.18     0.19     0.01     0.01     0.01     0.01     0.00
checkout-orphan-loose                   0.19     0.19     0.19     0.18     0.19     0.00     0.00     0.00     0.00     0.00
checkout-from-detached-loose-cold       7.80     4.17     4.17     4.05     4.09     4.07     4.26     4.23     4.18     4.08
checkout-from-detached-loose-warm       1.01     1.01     1.02     1.02     1.04     1.03     1.04     1.04     1.02     1.04
branch-contains-loose-cold             35.76    35.80    36.15    36.67    35.13    36.29    36.37    36.03    36.70    36.01
branch-contains-loose-warm             33.01    33.62    33.52    33.51    32.41    33.51    33.71    32.10    33.70    31.99
pack-refs-loose                         4.19     4.20     4.25     4.21     4.20     4.21     4.20     4.19     4.24     4.21
branch-packed-cold                      0.79     0.62     0.60     0.66     0.65     0.58     0.68     0.72     0.60     0.61
branch-packed-warm                      0.02     0.02     0.02     0.02     0.02     0.02     0.02     0.02     0.02     0.02
for-each-ref-packed-cold                0.96     0.97     0.97     0.93     0.89     0.92     0.98     0.96     0.92     0.96
for-each-ref-packed-warm                0.26     0.26     0.26     0.26     0.26     0.26     0.26     0.27     0.27     0.27
checkout-packed-cold                   16.14    16.16    16.74     2.04     2.03     2.09     2.06     2.13     2.03     2.00
checkout-packed-warm                    0.17     0.17     0.18     0.19     0.18     0.17     0.27     0.18     0.19     0.18
checkout-orphan-packed                  0.02     0.01     0.02     0.02     0.02     0.02     0.02     0.02     0.02     0.02
checkout-from-detached-packed-cold     16.24    15.96    16.80     1.99     2.06     2.01     2.08     2.10     1.97     1.96
checkout-from-detached-packed-warm     15.04    14.96    15.76     0.77     0.81     0.79     0.83     0.80     0.79     0.80
branch-contains-packed-cold            36.18    36.98    36.92    35.19    34.97    35.09    33.34    33.87    34.27    34.51
branch-contains-packed-warm            35.27    35.12    36.20    33.52    32.76    33.49    33.65    32.96    33.68    32.34
clone-loose-cold                        9.09     9.22     9.15     9.10     9.19     9.03     9.09     9.25     8.96     9.03
clone-loose-warm                        5.57     5.85     5.65     5.55     5.61     5.64     5.65     5.61     5.74     5.59
fetch-nothing-loose                     1.43     1.43     1.44     1.44     1.45     1.45     1.46     1.44     1.44     1.44
pack-refs                               0.08     0.08     0.08     0.08     0.09     0.08     0.09     0.08     0.08     0.08
fetch-nothing-packed                    1.44     1.43     1.44     1.44     1.44     1.44     1.44     1.44     1.44     1.44
clone-packed-cold                       1.35     1.26     1.30     1.32     1.28     1.35     1.38     1.35     1.29     1.21
clone-packed-warm                       0.36     0.35     0.35     0.36     0.36     0.36     0.35     0.36     0.37     0.35
fetch-everything-cold                  30.29    30.01    29.79    29.04    29.84    29.25    29.30    29.26    29.76    29.30
fetch-everything-warm                  26.20    26.04    26.40    25.60    26.22    25.83    25.82    25.85    26.68    25.73
===================================  =======  =======  =======  =======  =======  =======  =======  =======  =======  =======


[0] f696543 (tag: v1.7.6) Git 1.7.6
[1] 703f05a (tag: v1.7.7) Git 1.7.7
[2] 27897d2 (origin/master) Merge remote-tracking branch 'gitster/mh/iterate-refs'
[3] 558b49c is_refname_available(): reimplement using do_for_each_ref_in_list()
[4] 1658397 Store references hierarchically
[5] 5f5a126 get_ref_dir(): add a recursive option
[6] a306af1 get_ref_dir(): read one whole directory before descending into subdirs
[7] fd53cf7 add_ref(): change to take a (struct ref_entry *) as second argument
[8] 9944c7f (origin/testing) read_packed_refs(): keep track of the directory being worked in
[9] cb75c57 (origin/ok, origin/hierarchical-refs, origin/HEAD) refs.c: call clear_cached_ref_cache() from repack_without_ref()


^ permalink raw reply

* Re: Recovering Committed Changes in a Detached Head?
From: Nguyen Thai Ngoc Duy @ 2011-10-09  5:52 UTC (permalink / raw)
  To: Martin Fick; +Cc: SZEDER Gábor, Daly Gutierrez, git
In-Reply-To: <ab706826-75df-4410-941e-6b40ec92713c@email.android.com>

On Sun, Oct 9, 2011 at 9:00 AM, Martin Fick <mfick@codeaurora.org> wrote:
>>git reflog to the rescue.  For your example above it will output
>>something like this:
>>
>>deadbeef HEAD@{0}: checkout: moving from
>>92aa5381b9f7229523dba42aa94735c30f173451 to New_Branch
>>  92aa5381 HEAD@{1}: commit: Committing this in the Detached Head
>>3a5bb38a HEAD@{2}: checkout: moving from master to
>>3a5bb38a83c00f7acab573f0ec836577143200aa
>>  deafbabe HEAD@{3}: ...
>>  ...
>>
>>There you see the first line of the commit message from your "lost"
>>commit, and you can do
>>
>>  git checkout -b lost_detached_head 92aa5381
>>
>>and you get a branch pointing to that commit you made while on
>>detached head, and you can work with it as usual.
>
> While rflog is cool, I can't help but think that git could be even more helpful for these scenarios.
>
> First, maybe git could create refs for these automatically, perhaps with a name like orphans/1?  Maybe these refs would only be visible via git branch --orphans.

If I remember correctly, we don't have private ref namespace, any refs
created automatically this way could be pushed out by accident.
-- 
Duy

^ permalink raw reply

* Re: Recovering Committed Changes in a Detached Head?
From: Ronan Keryell @ 2011-10-09  7:46 UTC (permalink / raw)
  To: Nguyen Thai Ngoc Duy; +Cc: git
In-Reply-To: <CACsJy8CsMCju7joj2B2xbBSTF1vHjyuFeSZyPhTJisO2sU-Fqg@mail.gmail.com>

>>>>> On Sun, 9 Oct 2011 16:52:11 +1100, Nguyen Thai Ngoc Duy <pclouds@gmail.com> said:

    Nguyen> On Sun, Oct 9, 2011 at 9:00 AM, Martin Fick <mfick@codeaurora.org> wrote:

    >> While rflog is cool, I can't help but think that git could be
    >> even more helpful for these scenarios.

    >> First, maybe git could create refs for these automatically,
    >> perhaps with a name like orphans/1?  Maybe these refs would only
    >> be visible via git branch --orphans.

    Nguyen> If I remember correctly, we don't have private ref
    Nguyen> namespace, any refs created automatically this way could be
    Nguyen> pushed out by accident.

A way to avoid this could be to deal with this like git-stash works,
instead of relying on the branch machinery.

But anyway, I think there is a trade-off between keeping some references
to some hypothetical future use and preventing the garbage collector to
reclaim useless objects...
-- 
  Ronan KERYELL                      |\/  Phone:  +1 408 844 HPC0
  HPC Project, Inc.                  |/)  Cell:   +33 613 143 766
  5201 Great America Parkway #3241   K    Ronan.Keryell@hpc-project.com
  Santa Clara, CA 95054              |\   skype:keryell
  USA                                | \  http://hpc-project.com

^ permalink raw reply

* Re: Recovering Committed Changes in a Detached Head?
From: Matthieu Moy @ 2011-10-09  8:12 UTC (permalink / raw)
  To: Martin Fick; +Cc: SZEDER Gábor, Daly Gutierrez, git
In-Reply-To: <ab706826-75df-4410-941e-6b40ec92713c@email.android.com>

Martin Fick <mfick@codeaurora.org> writes:

>>git reflog to the rescue.  For your example above it will output
>>something like this:
>>
>>deadbeef HEAD@{0}: checkout: moving from
>>92aa5381b9f7229523dba42aa94735c30f173451 to New_Branch
>>  92aa5381 HEAD@{1}: commit: Committing this in the Detached Head
>>3a5bb38a HEAD@{2}: checkout: moving from master to
>>3a5bb38a83c00f7acab573f0ec836577143200aa
>>  deafbabe HEAD@{3}: ...
>>  ...
>>
>>There you see the first line of the commit message from your "lost"
>>commit, and you can do
>>
>>  git checkout -b lost_detached_head 92aa5381
>>
>>and you get a branch pointing to that commit you made while on
>>detached head, and you can work with it as usual.
>
> While rflog is cool, I can't help but think that git could be even more helpful for these scenarios.

Git has been showing a big scary warning when entering detached HEAD,
and now has another helpful one when leaving a commit orphan:

$ git checkout HEAD^
Note: checking out 'HEAD^'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at adcbd2f... foo

$ date > foo.txt; git add foo.txt; git commit -am "commited on detached HEAD"
[detached HEAD 9e9c4ef] commited on detached HEAD
 1 files changed, 1 insertions(+), 1 deletions(-)

$ git checkout master
Warning: you are leaving 1 commit behind, not connected to
any of your branches:

  9e9c4ef commited on detached HEAD

If you want to keep them by creating a new branch, this may be a good time
to do so with:

 git branch new_branch_name 9e9c4efeca049ca559541595c9ca4a3380dee523

Switched to branch 'master'

(since 8e2dc6ac06ae90, Junio C Hamano, Fri Feb 18 16:04:47 2011, commit:
give final warning when reattaching HEAD to leave commits behind)

I think these warnings are (scary and big) enough.

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

^ permalink raw reply

* Re: [PATCH 6/6] revert: Simplify passing command-line arguments around
From: Ramkumar Ramachandra @ 2011-10-09  8:28 UTC (permalink / raw)
  To: Tay Ray Chuan
  Cc: Git List, Jonathan Nieder, Junio C Hamano, Jeff King,
	Daniel Barkalow, Christian Couder
In-Reply-To: <CALUzUxo=xN735+=Yz9eS_VSW3fpiTeng9s-66qM0Jno40-DPXQ@mail.gmail.com>

Hi Tay,

Tay Ray Chuan writes:
> On Sun, Oct 9, 2011 at 1:36 AM, Ramkumar Ramachandra <artagnon@gmail.com> wrote:
>> [rr: minor improvements, commit message]
>
> This "[]" could go below, under the 3-dash (but before the stat):

Actually, I intended to put it in the commit message.  Seems to be
idiomatic: grep the log for "\[jc:" etc.

Thanks.

-- Ram

^ permalink raw reply

* Re: [PATCH 6/6] revert: Simplify passing command-line arguments around
From: Jonathan Nieder @ 2011-10-09  8:53 UTC (permalink / raw)
  To: Ramkumar Ramachandra
  Cc: Tay Ray Chuan, Git List, Junio C Hamano, Jeff King,
	Daniel Barkalow, Christian Couder
In-Reply-To: <CALkWK0kA=zhpsmYhjMwv11xyHNhA0Ps=BjUDao0+HFLMKnADUg@mail.gmail.com>

Ramkumar Ramachandra wrote:

> Actually, I intended to put it in the commit message.  Seems to be
> idiomatic: grep the log for "\[jc:" etc.

More important than the idiom is the intent.  Presumably that intent
was something like "I wrote the commit message, so if it makes you
scratch your head, blame me, not Jonathan; and I made some other
(minor) improvements, so consider blaming me even if it's the
functional part that makes you scratch your head."

Sorry I haven't had a chance to look over the patch yet.  Is it
supposed to introduce a behavior change, does it prepare for some
future change, or is it just a cleanup?

^ permalink raw reply

* [PATCH da/difftool-mergtool-refactor] Makefile: fix permissions of mergetools/ checked out with permissive umask
From: Jonathan Nieder @ 2011-10-09  9:17 UTC (permalink / raw)
  To: David Aguilar
  Cc: Junio C Hamano, git, Tanguy Ortolo, Charles Bailey,
	Sebastian Schuberth
In-Reply-To: <1313652227-48545-4-git-send-email-davvid@gmail.com>

Ever since mergetool--lib was split into multiple files in
v1.7.7-rc0~3^2~1 (2011-08-18), the Makefile takes care to reset umask
and use tar --no-owner when installing merge tool definitions to
$(gitexecdir)/mergetools/.  Unfortunately it does not take into
account the possibility that the permission bits of the files being
copied might already be wrong.

Rather than fixing the "tar" incantation and making it even more
complicated, let's just use the "install" utility.  This only means
losing the ability to install executables and subdirectories of
mergetools/, which wasn't used.

Noticed by installing from a copy of git checked out with umask 002.
Compare v1.6.0.3~81^2 (Fix permission bits on sources checked out with
an overtight umask, 2008-08-21).

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
David Aguilar wrote:

> +++ b/Makefile
[...]
> @@ -2266,6 +2274,9 @@ install: all
>  	$(INSTALL) -m 644 $(SCRIPT_LIB) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
>  	$(INSTALL) $(install_bindir_programs) '$(DESTDIR_SQ)$(bindir_SQ)'
>  	$(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install
> +	$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(mergetools_instdir_SQ)'
> +	(cd mergetools && $(TAR) cf - .) | \
> +	(cd '$(DESTDIR_SQ)$(mergetools_instdir_SQ)' && umask 022 && $(TAR) xof -)

Last month I tried this out and found that, strangely, my files under
/usr/lib/git-core/mergetools/ had the g+w bit set.  Leading me to
wonder: does the "umask" here have any effect at all?

Since debian/rules install is run as root, the default is for tar to
act as thought --preserve-permissions were passed, so the umask when
running "tar" is not relevant.  Luckily I think "tar" is overkill
here, anyway.

Thoughts?  Sorry to have taken so long to send this out.

 Makefile |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 1e91b19c..e27755e7 100644
--- a/Makefile
+++ b/Makefile
@@ -2275,8 +2275,7 @@ install: all
 	$(INSTALL) $(install_bindir_programs) '$(DESTDIR_SQ)$(bindir_SQ)'
 	$(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install
 	$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(mergetools_instdir_SQ)'
-	(cd mergetools && $(TAR) cf - .) | \
-	(cd '$(DESTDIR_SQ)$(mergetools_instdir_SQ)' && umask 022 && $(TAR) xof -)
+	$(INSTALL) -m 644 mergetools/* '$(DESTDIR_SQ)$(mergetools_instdir_SQ)'
 ifndef NO_PERL
 	$(MAKE) -C perl prefix='$(prefix_SQ)' DESTDIR='$(DESTDIR_SQ)' install
 	$(MAKE) -C gitweb install
-- 
1.7.7.rc1

^ permalink raw reply related

* Re: [PATCH 6/6] revert: Simplify passing command-line arguments around
From: Ramkumar Ramachandra @ 2011-10-09  9:04 UTC (permalink / raw)
  To: Jonathan Nieder
  Cc: Tay Ray Chuan, Git List, Junio C Hamano, Jeff King,
	Daniel Barkalow, Christian Couder
In-Reply-To: <20111009085306.GA9209@elie.hsd1.il.comcast.net>

Hi Jonathan,

Jonathan Nieder writes:
> More important than the idiom is the intent.  Presumably that intent
> was something like "I wrote the commit message, so if it makes you
> scratch your head, blame me, not Jonathan; and I made some other
> (minor) improvements, so consider blaming me even if it's the
> functional part that makes you scratch your head."

Exactly.

> Sorry I haven't had a chance to look over the patch yet.  Is it
> supposed to introduce a behavior change, does it prepare for some
> future change, or is it just a cleanup?

Prepare for some future change.  See $gmane/179282 for original discussion.

-- Ram

^ permalink raw reply

* Re: [PATCH 6/6] revert: Simplify passing command-line arguments around
From: Jonathan Nieder @ 2011-10-09  9:24 UTC (permalink / raw)
  To: Ramkumar Ramachandra
  Cc: Tay Ray Chuan, Git List, Junio C Hamano, Jeff King,
	Daniel Barkalow, Christian Couder
In-Reply-To: <CALkWK0niwg1Ogs+xBr8NHEce-MUUzPc_Upn0ZKRi3iCZ6fA4BQ@mail.gmail.com>

Ramkumar Ramachandra wrote:
> Jonathan Nieder writes:

>> Sorry I haven't had a chance to look over the patch yet.  Is it
>> supposed to introduce a behavior change, does it prepare for some
>> future change, or is it just a cleanup?
>
> Prepare for some future change.  See $gmane/179282 for original discussion.

Thanks, but I shouldn't have had to ask.  Care to fix the commit
message? :)

^ permalink raw reply

* Re: A Basic Git Question About File Tracking [ANSWERED]
From: Jakub Narebski @ 2011-10-09  9:37 UTC (permalink / raw)
  To: Jon Forrest; +Cc: git, Jonathan Nieder
In-Reply-To: <4E910A14.7040801@gmail.com>

On Sun, 9 Oct 2011, Jon Forrest wrote:
> On 10/8/2011 6:17 PM, Jakub Narebski wrote:
> 
> > You seem to be under [false] impression that git commit is about
> > _changes_ / _changeset_.
> 
> This is correct. The Pro Git book says:
> 
> "You stage these modified files and then commit
> all your staged changes"
> 
> Plus, even "git status" tells me
> 
> $ git status
> # On branch master
> # Changes to be committed:

Well, that is because the two representations: delta / changeset
("differential") representation and snapshot ("integral") representation
are related, and [in practice] one can be transformed into the other.

Sometimes it is better to think about commit as representing changeset
from parent commit, sometimes it is better to think of a commit as of
snapshot of a state of project.

But under the hood git model is snapshot-based.

> But I see my error. Below is what I hope is a clear
> explanation of what I didn't understand. It presumes
> that the reader understands the git objects model.
> Please let me know if anything is incorrect.
> ----------
> When you "git add" a file two things happen:
> 
> 1) The file is copied to the git objects tree.

Actually it is file _contents_ that is copied to git object _store_.

> This location where the file is copied depends
> on the hash of the file's content.

I'd say that this is unnecessary implementation detail of "loose"
object format.  I would say that _identifier_ of added object is
based on its contents.

> 
> 2) An entry for the file is added to the git index.
> This entry includes the same hash that was mentioned
> in #1.

Yes.
 
> A tracked file has an entry in the git index file.

Yes.

> A copy of the file also exists in the objects tree.

A copy of a _contents_ of a file at specific point of time
exists in object _store_ (not necessary object tree, as it
can be packed).
 
> When you run 'git status', git computes the hash of
> every file in your working directory and looks
> up each file in the index. If the file isn't found
> then the file is shown as untracked.

Sidenote: git stores in the index also stats of a file (modification
time etc.) so it is possible to avoid recomputing the hash of every 
file.
 
> When you do a commit, the hash values of everything
> in the index are copied into a tree object. The hash
> value of the tree object is then placed in a commit object.

True, though I would probably state it a bit differently.

> No copies of tracked files in the working directory are
> made at commit time. This is because the files were already
> copied into the objects tree when 'git add' was run.
> This is one reason why git commits are so fast.

Well, there is also "git commit -a", but it is true that git
copies into object store only those tracked files that changed.

Also I think that the main reason that git commits are fast is
that they are local operation, and not over the network as in the
case of centralized version control systems.
 
-- 
Jakub Narebski
Poland

^ permalink raw reply

* Re: [PATCH 6/6] Retain caches of submodule refs
From: Michael Haggerty @ 2011-10-09 11:12 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt
In-Reply-To: <7v4o1hgemp.fsf@alter.siamese.dyndns.org>

On 08/17/2011 12:45 AM, Junio C Hamano wrote:
> All the changes except for this one made sense to me, but I am not sure
> about this one. How often do we look into different submodule refs in the
> same process over and over again?

I am having pangs of uncertainty about this patch.

Previous to this patch, the submodule reference cache was only used for
the duration of one call to do_for_each_ref().  (It was not *discarded*
until later, but the old cache was never reused.)  Therefore, the
submodule reference cache was implicitly invalidated between successive
uses.

After this change, submodule ref caches are invalidated whenever
invalidate_cached_refs() is called.  But this function is static, and it
is only called when main-module refs are changed.

AFAIK there is no way within refs.c to add, modify, or delete a
submodule reference.  But if other code modifies submodule references
directly, then the submodule ref cache in refs.c would become stale.
Moreover, there is currently no API for invalidating the cache.

So I think I need help from a submodule guru (Heiko?) who can tell me
what is done with submodule references and whether they might be
modified while a git process is executing in the main module.  If so,
then either this patch has to be withdrawn, or more work has to be put
in to make such code invalidate the submodule reference cache.

Sorry for the oversight, but I forgot that not all code necessarily uses
the refs.c API when dealing with references (a regrettable situation, BTW).

Michael

-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/

^ permalink raw reply

* [PATCH 1/2] xdiff: factor out get_func_line()
From: René Scharfe @ 2011-10-09 11:34 UTC (permalink / raw)
  To: Git Mailing List; +Cc: Sverre Rabbelier, Junio C Hamano

Move the code to search for a function line to be shown in the hunk
header into its own function and to make returning the length-limited
result string easier, introduce struct func_line.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
 xdiff/xemit.c |   43 +++++++++++++++++++++++++++----------------
 1 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/xdiff/xemit.c b/xdiff/xemit.c
index 277e2ee..64eb17a 100644
--- a/xdiff/xemit.c
+++ b/xdiff/xemit.c
@@ -100,14 +100,35 @@ static int xdl_emit_common(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
 	return 0;
 }
 
+struct func_line {
+	long len;
+	char buf[80];
+};
+
+static void get_func_line(xdfenv_t *xe, xdemitconf_t const *xecfg,
+			  struct func_line *func_line, long start, long limit)
+{
+	find_func_t ff = xecfg->find_func ? xecfg->find_func : def_ff;
+	long l, size = sizeof(func_line->buf);
+	char *buf = func_line->buf;
+
+	for (l = start; l > limit && 0 <= l; l--) {
+		const char *rec;
+		long reclen = xdl_get_rec(&xe->xdf1, l, &rec);
+		long len = ff(rec, reclen, buf, size, xecfg->find_func_priv);
+		if (len >= 0) {
+			func_line->len = len;
+			break;
+		}
+	}
+}
+
 int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
 		  xdemitconf_t const *xecfg) {
 	long s1, s2, e1, e2, lctx;
 	xdchange_t *xch, *xche;
-	char funcbuf[80];
-	long funclen = 0;
 	long funclineprev = -1;
-	find_func_t ff = xecfg->find_func ?  xecfg->find_func : def_ff;
+	struct func_line func_line = { 0 };
 
 	if (xecfg->flags & XDL_EMIT_COMMON)
 		return xdl_emit_common(xe, xscr, ecb, xecfg);
@@ -130,22 +151,12 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
 		 */
 
 		if (xecfg->flags & XDL_EMIT_FUNCNAMES) {
-			long l;
-			for (l = s1 - 1; l >= 0 && l > funclineprev; l--) {
-				const char *rec;
-				long reclen = xdl_get_rec(&xe->xdf1, l, &rec);
-				long newfunclen = ff(rec, reclen, funcbuf,
-						     sizeof(funcbuf),
-						     xecfg->find_func_priv);
-				if (newfunclen >= 0) {
-					funclen = newfunclen;
-					break;
-				}
-			}
+			get_func_line(xe, xecfg, &func_line,
+				      s1 - 1, funclineprev);
 			funclineprev = s1 - 1;
 		}
 		if (xdl_emit_hunk_hdr(s1 + 1, e1 - s1, s2 + 1, e2 - s2,
-				      funcbuf, funclen, ecb) < 0)
+				      func_line.buf, func_line.len, ecb) < 0)
 			return -1;
 
 		/*
-- 
1.7.7

^ permalink raw reply related

* Re: [PATCH] git-difftool: allow skipping file by typing 'n' at prompt
From: Charles Bailey @ 2011-10-09 11:26 UTC (permalink / raw)
  To: Sitaram Chamarty; +Cc: Junio C Hamano, Phil Hord, Sitaram Chamarty, git
In-Reply-To: <20111008131015.GA28213@sita-lt.atc.tcs.com>

On Sat, Oct 08, 2011 at 06:40:15PM +0530, Sitaram Chamarty wrote:
> 
>  git-difftool--helper.sh |    9 +++++----
>  t/t7800-difftool.sh     |   44 +++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 48 insertions(+), 5 deletions(-)
> 
> diff --git a/git-difftool--helper.sh b/git-difftool--helper.sh
> index 8452890..0468446 100755
> --- a/git-difftool--helper.sh
> +++ b/git-difftool--helper.sh
> @@ -38,15 +38,16 @@ launch_merge_tool () {
>  
>  	# $LOCAL and $REMOTE are temporary files so prompt
>  	# the user with the real $MERGED name before launching $merge_tool.
> +	ans=y
>  	if should_prompt
>  	then
>  		printf "\nViewing: '$MERGED'\n"
>  		if use_ext_cmd
>  		then
> -			printf "Hit return to launch '%s': " \
> +			printf "Launch '%s' [Y/n]: " \
>  				"$GIT_DIFFTOOL_EXTCMD"
>  		else
> -			printf "Hit return to launch '%s': " "$merge_tool"
> +			printf "Launch '%s' [Y/n]: " "$merge_tool"
>  		fi
>  		read ans
>  	fi
> @@ -54,9 +55,9 @@ launch_merge_tool () {
>  	if use_ext_cmd
>  	then
>  		export BASE
> -		eval $GIT_DIFFTOOL_EXTCMD '"$LOCAL"' '"$REMOTE"'
> +		test "$ans" != "n" && eval $GIT_DIFFTOOL_EXTCMD '"$LOCAL"' '"$REMOTE"'
>  	else
> -		run_merge_tool "$merge_tool"
> +		test "$ans" != "n" && run_merge_tool "$merge_tool"
>  	fi
>  }

It's a minor point but for me, this looks a little more difficult to
follow than it needs to be.

Why do we need to hold on to 'ans' for so long? With the new prompt,
if we ever 'read ans' we always want to return from the
launch_merge_tool without doing anything else if we read "n". I think
it's easier to follow if we just change 'read ans' and leave the 'if
use_ext_cmd' clauses alone. Perhaps some people don't like the early
return, though?

Charles.


E.g. (for discussion, untested):

diff --git a/git-difftool--helper.sh b/git-difftool--helper.sh
index 8452890..b668a12 100755
--- a/git-difftool--helper.sh
+++ b/git-difftool--helper.sh
@@ -43,12 +43,16 @@ launch_merge_tool () {
                printf "\nViewing: '$MERGED'\n"
                if use_ext_cmd
                then
-                       printf "Hit return to launch '%s': " \
+                       printf "Launch '%s' [Y/n]: " \
                                "$GIT_DIFFTOOL_EXTCMD"
                else
-                       printf "Hit return to launch '%s': " "$merge_tool"
+                       printf "Launch '%s' [Y/n]: " "$merge_tool"
+               fi
+
+               if read ans && test "$ans" = "n"
+               then
+                       return
                fi
-               read ans
        fi

        if use_ext_cmd

^ permalink raw reply related

* [PATCH 2/2] diff: add option to show whole functions as context
From: René Scharfe @ 2011-10-09 11:36 UTC (permalink / raw)
  To: Git Mailing List; +Cc: Sverre Rabbelier, Junio C Hamano
In-Reply-To: <4E9186D9.4060805@lsrfire.ath.cx>

Add the option -W/--function-context to git diff.  It is similar to
the same option of git grep and expands the context of change hunks
so that the whole surrounding function is shown.  This "natural"
context can allow changes to be understood better.

Note: GNU patch doesn't like diffs generated with the new option;
it seems to expect context lines to be the same before and after
changes.  git apply doesn't complain.

This implementation has the same shortcoming as the one in grep,
namely that there is no way to explicitly find the end of a
function.  That means that a few lines of extra context are shown,
right up to the next recognized function begins.  It's already
useful in its current form, though.


The function get_func_line() in xdiff/xemit.c is extended to work
forward as well as backward to find post-context as well as
pre-context.  It returns the position of the first found matching
line.  The func_line parameter is made optional, as we don't need
it for -W.

The enhanced function is then used in xdl_emit_diff() to extend
the context as needed.  If the added context overlaps with the
next change, it is merged into the current hunk.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
 Documentation/diff-options.txt   |    4 ++
 diff.c                           |    8 +++
 diff.h                           |    1 +
 t/t4051-diff-function-context.sh |   92 ++++++++++++++++++++++++++++++++++++++
 xdiff/xdiff.h                    |    1 +
 xdiff/xemit.c                    |   54 ++++++++++++++++++++---
 6 files changed, 154 insertions(+), 6 deletions(-)
 create mode 100644 t/t4051-diff-function-context.sh

diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index b620b3a..1ce4ae3 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -404,6 +404,10 @@ endif::git-format-patch[]
 	Show the context between diff hunks, up to the specified number
 	of lines, thereby fusing hunks that are close to each other.
 
+-W::
+--function-context::
+	Show whole surrounding functions of changes.
+
 ifndef::git-format-patch[]
 --exit-code::
 	Make the program exit with codes similar to diff(1).
diff --git a/diff.c b/diff.c
index fcc0078..42c4891 100644
--- a/diff.c
+++ b/diff.c
@@ -2169,6 +2169,8 @@ static void builtin_diff(const char *name_a,
 		xecfg.ctxlen = o->context;
 		xecfg.interhunkctxlen = o->interhunkcontext;
 		xecfg.flags = XDL_EMIT_FUNCNAMES;
+		if (DIFF_OPT_TST(o, FUNCCONTEXT))
+			xecfg.flags |= XDL_EMIT_FUNCCONTEXT;
 		if (pe)
 			xdiff_set_find_func(&xecfg, pe->pattern, pe->cflags);
 		if (!diffopts)
@@ -3530,6 +3532,12 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
 	else if (opt_arg(arg, '\0', "inter-hunk-context",
 			 &options->interhunkcontext))
 		;
+	else if (!strcmp(arg, "-W"))
+		DIFF_OPT_SET(options, FUNCCONTEXT);
+	else if (!strcmp(arg, "--function-context"))
+		DIFF_OPT_SET(options, FUNCCONTEXT);
+	else if (!strcmp(arg, "--no-function-context"))
+		DIFF_OPT_CLR(options, FUNCCONTEXT);
 	else if ((argcount = parse_long_opt("output", av, &optarg))) {
 		options->file = fopen(optarg, "w");
 		if (!options->file)
diff --git a/diff.h b/diff.h
index 8c66b59..0c51724 100644
--- a/diff.h
+++ b/diff.h
@@ -79,6 +79,7 @@ typedef struct strbuf *(*diff_prefix_fn_t)(struct diff_options *opt, void *data)
 #define DIFF_OPT_IGNORE_DIRTY_SUBMODULES (1 << 26)
 #define DIFF_OPT_OVERRIDE_SUBMODULE_CONFIG (1 << 27)
 #define DIFF_OPT_DIRSTAT_BY_LINE     (1 << 28)
+#define DIFF_OPT_FUNCCONTEXT         (1 << 29)
 
 #define DIFF_OPT_TST(opts, flag)    ((opts)->flags & DIFF_OPT_##flag)
 #define DIFF_OPT_SET(opts, flag)    ((opts)->flags |= DIFF_OPT_##flag)
diff --git a/t/t4051-diff-function-context.sh b/t/t4051-diff-function-context.sh
new file mode 100644
index 0000000..001d678
--- /dev/null
+++ b/t/t4051-diff-function-context.sh
@@ -0,0 +1,92 @@
+#!/bin/sh
+
+test_description='diff function context'
+
+. ./test-lib.sh
+. "$TEST_DIRECTORY"/diff-lib.sh
+
+
+cat <<\EOF >hello.c
+#include <stdio.h>
+
+static int a(void)
+{
+	/*
+	 * Dummy.
+	 */
+}
+
+static int hello_world(void)
+{
+	/* Classic. */
+	printf("Hello world.\n");
+
+	/* Success! */
+	return 0;
+}
+static int b(void)
+{
+	/*
+	 * Dummy, too.
+	 */
+}
+
+int main(int argc, char **argv)
+{
+	a();
+	b();
+	return hello_world();
+}
+EOF
+
+test_expect_success 'setup' '
+	git add hello.c &&
+	test_tick &&
+	git commit -m initial &&
+
+	grep -v Classic <hello.c >hello.c.new &&
+	mv hello.c.new hello.c
+'
+
+cat <<\EOF >expected
+diff --git a/hello.c b/hello.c
+--- a/hello.c
++++ b/hello.c
+@@ -10,8 +10,7 @@ static int a(void)
+ static int hello_world(void)
+ {
+-	/* Classic. */
+ 	printf("Hello world.\n");
+ 
+ 	/* Success! */
+ 	return 0;
+ }
+EOF
+
+test_expect_success 'diff -U0 -W' '
+	git diff -U0 -W >actual &&
+	compare_diff_patch actual expected
+'
+
+cat <<\EOF >expected
+diff --git a/hello.c b/hello.c
+--- a/hello.c
++++ b/hello.c
+@@ -9,9 +9,8 @@ static int a(void)
+ 
+ static int hello_world(void)
+ {
+-	/* Classic. */
+ 	printf("Hello world.\n");
+ 
+ 	/* Success! */
+ 	return 0;
+ }
+EOF
+
+test_expect_success 'diff -W' '
+	git diff -W >actual &&
+	compare_diff_patch actual expected
+'
+
+test_done
diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h
index 4beb10c..00d36c3 100644
--- a/xdiff/xdiff.h
+++ b/xdiff/xdiff.h
@@ -43,6 +43,7 @@ extern "C" {
 
 #define XDL_EMIT_FUNCNAMES (1 << 0)
 #define XDL_EMIT_COMMON (1 << 1)
+#define XDL_EMIT_FUNCCONTEXT (1 << 2)
 
 #define XDL_MMB_READONLY (1 << 0)
 
diff --git a/xdiff/xemit.c b/xdiff/xemit.c
index 64eb17a..2e669c3 100644
--- a/xdiff/xemit.c
+++ b/xdiff/xemit.c
@@ -105,22 +105,27 @@ struct func_line {
 	char buf[80];
 };
 
-static void get_func_line(xdfenv_t *xe, xdemitconf_t const *xecfg,
+static long get_func_line(xdfenv_t *xe, xdemitconf_t const *xecfg,
 			  struct func_line *func_line, long start, long limit)
 {
 	find_func_t ff = xecfg->find_func ? xecfg->find_func : def_ff;
-	long l, size = sizeof(func_line->buf);
-	char *buf = func_line->buf;
+	long l, size, step = (start > limit) ? -1 : 1;
+	char *buf, dummy[1];
 
-	for (l = start; l > limit && 0 <= l; l--) {
+	buf = func_line ? func_line->buf : dummy;
+	size = func_line ? sizeof(func_line->buf) : sizeof(dummy);
+
+	for (l = start; l != limit && 0 <= l && l < xe->xdf1.nrec; l += step) {
 		const char *rec;
 		long reclen = xdl_get_rec(&xe->xdf1, l, &rec);
 		long len = ff(rec, reclen, buf, size, xecfg->find_func_priv);
 		if (len >= 0) {
-			func_line->len = len;
-			break;
+			if (func_line)
+				func_line->len = len;
+			return l;
 		}
 	}
+	return -1;
 }
 
 int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
@@ -139,6 +144,17 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
 		s1 = XDL_MAX(xch->i1 - xecfg->ctxlen, 0);
 		s2 = XDL_MAX(xch->i2 - xecfg->ctxlen, 0);
 
+		if (xecfg->flags & XDL_EMIT_FUNCCONTEXT) {
+			long fs1 = get_func_line(xe, xecfg, NULL, xch->i1, -1);
+			if (fs1 < 0)
+				fs1 = 0;
+			if (fs1 < s1) {
+				s2 -= s1 - fs1;
+				s1 = fs1;
+			}
+		}
+
+ again:
 		lctx = xecfg->ctxlen;
 		lctx = XDL_MIN(lctx, xe->xdf1.nrec - (xche->i1 + xche->chg1));
 		lctx = XDL_MIN(lctx, xe->xdf2.nrec - (xche->i2 + xche->chg2));
@@ -146,6 +162,32 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
 		e1 = xche->i1 + xche->chg1 + lctx;
 		e2 = xche->i2 + xche->chg2 + lctx;
 
+		if (xecfg->flags & XDL_EMIT_FUNCCONTEXT) {
+			long fe1 = get_func_line(xe, xecfg, NULL,
+						 xche->i1 + xche->chg1,
+						 xe->xdf1.nrec);
+			if (fe1 < 0)
+				fe1 = xe->xdf1.nrec;
+			if (fe1 > e1) {
+				e2 += fe1 - e1;
+				e1 = fe1;
+			}
+
+			/*
+			 * Overlap with next change?  Then include it
+			 * in the current hunk and start over to find
+			 * its new end.
+			 */
+			if (xche->next) {
+				long l = xche->next->i1;
+				if (l <= e1 ||
+				    get_func_line(xe, xecfg, NULL, l, e1) < 0) {
+					xche = xche->next;
+					goto again;
+				}
+			}
+		}
+
 		/*
 		 * Emit current hunk header.
 		 */
-- 
1.7.7

^ permalink raw reply related

* Re: [PATCH da/difftool-mergtool-refactor] Makefile: fix permissions of mergetools/ checked out with permissive umask
From: Jonathan Nieder @ 2011-10-09 11:43 UTC (permalink / raw)
  To: David Aguilar
  Cc: Junio C Hamano, git, Tanguy Ortolo, Charles Bailey,
	Sebastian Schuberth
In-Reply-To: <20111009091617.GA29150@elie.hsd1.il.comcast.net>

Jonathan Nieder wrote:

> ---
[...]
> Since debian/rules install is run as root, the default is for tar to
> act as thought --preserve-permissions were passed

I should have said: "when 'make install' is run as root, ...".

Typically people building git for private use would run "make install"
as root when installing to /usr/local, but as an unprivileged user
when installing to $HOME.  The RPM packaging runs "make install"
without special privileges and the Debian packaging runs it as (fake)
root, iirc.

Sorry for the lack of clarity.

^ permalink raw reply

* Re: [PATCH v3 5/5] attr.c: respect core.ignorecase when matching attribute patterns
From: Michael Haggerty @ 2011-10-09 15:16 UTC (permalink / raw)
  To: Brandon Casey; +Cc: gitster, git, peff, j.sixt, Brandon Casey
In-Reply-To: <U4wiHVyDLLG1PhI-8iY3YhHT7CEcTMEfg9MCDSaeuwAkg0N1a5wRE5NXaKAVQx8kpEYt75REVpRavoc-HiKe6rLk2AUepzHWptkevo08MRbGyWxqBHT_rySLemcbi66NKLRXwFGtaRQ@cipher.nrlssc.navy.mil>

On 10/06/2011 08:22 PM, Brandon Casey wrote:
> The last set of tests is performed only on a case-insensitive filesystem.
> Those tests make sure that git handles the case where the .gitignore file
> resides in a subdirectory and the user supplies a path that does not match
> the case in the filesystem.  In that case^H^H^H^Hsituation, part of the
> path supplied by the user is effectively interpreted case-insensitively,
> and part of it is dependent on the setting of core.ignorecase.  git should
> only match the portion of the path below the directory holding the
> .gitignore file according to the setting of core.ignorecase.

Isn't this a rather perverse scenario?  It is hard to imagine that
anybody *wants* part of a single filename to be matched
case-insensitively and another part to be matched case-sensitively.
ISTM that a person who is using a case-insensitive filesystem and has
core-ignorecase=false is (1) a glutton for punishment and (2) probably
very careful to make sure that the case of all pathnames is correct.  So
such a person is not likely to benefit from this schizophrenic behavior.

> [...]  If git instead built the attr
> stack by scanning the repository, then the paths in the origin field would
> not necessarily match the paths supplied by the user.  If someone makes a
> change like that in the future, these tests will notice.

Your decision to treat path names as partly case-insensitive will make
this kind of improvement considerably more complicated.

Therefore, weighing the negligible benefit of declaring this
schizophrenic behavior against the potential big pain of remaining
backwards-compatible with this behavior, I suggest that we either (1)
declare that when core.ignorecase=false then the *whole* filenames
(including the path leading up to the .gitignore file) must match
case-sensitively, or (2) declare the behavior in this situation to be
undefined so that nobody thinks they should depend on it.

But given that I'm a potential implementer but not a potential Windows
user, perhaps my judgment is biased...

Michael

-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/

^ permalink raw reply

* Re: [PATCH 1/3] traverse_trees(): allow pruning with pathspec
From: Michael Haggerty @ 2011-10-09 15:39 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Linus Torvalds, Nguyen Thai Ngoc Duy
In-Reply-To: <1314653603-7533-2-git-send-email-gitster@pobox.com>

On 08/29/2011 11:33 PM, Junio C Hamano wrote:
> diff --git a/tree-walk.c b/tree-walk.c
> index 33f749e..808bb55 100644
> --- a/tree-walk.c
> +++ b/tree-walk.c
> [...]
> @@ -376,16 +396,22 @@ int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info)
>  			mask |= 1ul << i;
>  			if (S_ISDIR(entry[i].mode))
>  				dirmask |= 1ul << i;
> +			e = &entry[i];
>  		}
>  		if (!mask)
>  			break;
> -		ret = info->fn(n, mask, dirmask, entry, info);
> -		if (ret < 0) {
> -			error = ret;
> -			if (!info->show_all_errors)
> -				break;
> +		interesting = prune_traversal(e, info, &base, interesting);

According to gcc 4.2.4 (though, strangely, not gcc 4.4.3):

tree-walk.c: In function ‘traverse_trees’:
tree-walk.c:347: warning: ‘e’ may be used uninitialized in this function

Michael

-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/

^ permalink raw reply

* Check revision and if no files modified (looking for svnversion equivalent)
From: fkater @ 2011-10-09 16:29 UTC (permalink / raw)
  To: git

Hi,

in my subversion software repository I use the 'svnversion'
command to do both:

- get the last revision (e.g. r1001)
- check for modified files not yet checked in (e.g. r1001 M)

Both information is required for the application's build
process (Makefiles):

- to display the version in the application
- to refuse to build a proper 'release' version if something
  was not checked in

Would there be a way to do both in git somehow?

 Felix

^ permalink raw reply

* Re: [PATCH] commit: teach --gpg-sign option
From: Michael J Gruber @ 2011-10-09 16:32 UTC (permalink / raw)
  Cc: Git Mailing List, Robin H. Johnson, Junio C Hamano
In-Reply-To: <4E8EBAFE.8020805@drmicha.warpmail.net>

Michael J Gruber venit, vidit, dixit 07.10.2011 10:40:
> [readding JCH to cc whom you dropped]
> Robin H. Johnson venit, vidit, dixit 07.10.2011 00:24:
>> On Wed, Oct 05, 2011 at 05:56:55PM -0700,  Junio C Hamano wrote:
>>> And this uses the gpg-interface.[ch] to allow signing the commit, i.e.
>>>
>>>     $ git commit --gpg-sign -m foo
>>>     You need a passphrase to unlock the secret key for
>>>     user: "Junio C Hamano <gitster@pobox.com>"
>>>     4096-bit RSA key, ID 96AFE6CB, created 2011-10-03 (main key ID 713660A7)
>>>
>>>     [master 8457d13] foo
>>>      1 files changed, 1 insertions(+), 0 deletions(-)
>> I like it, but I have a couple of questions: 
>> 1. Are the sig lines used in computed SHA1/commitid of a given commit (I
>>    see examples w/ --amend and that would usually change the SHA1)?
> 
> Yes, just like with tag objects.
> 
>> 2. Can we allow more than one person sign a commit?
> 
> I don't think we support it now (tags) but we could allow concatenating
> signatures since they are detached.

Quick update:
Sticking two signatures into a signed tag works perfectly with current
git, both signatures are verified and displayed.

So, it might make sense to have "commit --amend" append to an existing
signature.

> There's a somewhat delicate issue here: The signature (tag/commit) is a
> signature on the contents of the object, and is itself not part of the
> contents (or else we would have a chicken-egg-problem).
> 
> The sha1 of the object is determined by the content+header, i.e.
> including the signature.

NB: "header" is the wrong term here, it's "data" I think.

> So, by adding a signature, you change the sha1, but any existing
> signature remains valid.
> 
> This is also how you can try to achieve a specific sha1 for a given
> object content...
> 

^ 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