# most commonly used git commands?

26 messages from 2007-06-25 to 2007-07-01. Participants: Michael S. Tsirkin, Junio C Hamano, Johannes Schindelin, Josh Triplett, Martin Langhoff, Alex Riesen, Johannes Sixt, Jan Hudec.
Thread: https://gitlist.dev/t/8709

## Michael S. Tsirkin, 2007-06-25 06:40

Subject: most commonly used git commands?
Message-ID: <20070625064017.GA2839@mellanox.co.il>
URL: https://gitlist.dev/e/20070625064017.GA2839%40mellanox.co.il

```
I did this by mistake:

$git fet linux-2.6
git: 'fet' is not a git-command

The most commonly used git commands are:
   add     Add file contents to the changeset to be committed next
   apply   Apply a patch on a git index file and a working tree
(use 'git help -a' to get a list of all installed git commands)

why does git say that add and apply are most commonly used git commands?

-- 
MST

```

## Junio C Hamano, 2007-06-25 07:10

Subject: Re: most commonly used git commands?
Message-ID: <7vlke833wr.fsf@assigned-by-dhcp.pobox.com>
URL: https://gitlist.dev/e/7vlke833wr.fsf%40assigned-by-dhcp.pobox.com
In-Reply-To: <20070625064017.GA2839@mellanox.co.il>

```
"Michael S. Tsirkin" <mst@dev.mellanox.co.il> writes:

> I did this by mistake:
>
> $git fet linux-2.6
> git: 'fet' is not a git-command
>
> The most commonly used git commands are:
>    add     Add file contents to the changeset to be committed next
>    apply   Apply a patch on a git index file and a working tree
> (use 'git help -a' to get a list of all installed git commands)
>
> why does git say that add and apply are most commonly used git commands?

Perhaps they are most commonly used by the person who came up
with that list first ;-)?

I think "add" deserves to be there, I am not sure "apply" is.

```

## Michael S. Tsirkin, 2007-06-25 07:17

Subject: Re: most commonly used git commands?
Message-ID: <20070625071752.GB15343@mellanox.co.il>
URL: https://gitlist.dev/e/20070625071752.GB15343%40mellanox.co.il
In-Reply-To: <7vlke833wr.fsf@assigned-by-dhcp.pobox.com>

```
> Quoting Junio C Hamano <gitster@pobox.com>:
> Subject: Re: most commonly used git commands?
> 
> "Michael S. Tsirkin" <mst@dev.mellanox.co.il> writes:
> 
> > I did this by mistake:
> >
> > $git fet linux-2.6
> > git: 'fet' is not a git-command
> >
> > The most commonly used git commands are:
> >    add     Add file contents to the changeset to be committed next
> >    apply   Apply a patch on a git index file and a working tree
> > (use 'git help -a' to get a list of all installed git commands)
> >
> > why does git say that add and apply are most commonly used git commands?
> 
> Perhaps they are most commonly used by the person who came up
> with that list first ;-)?
> 
> I think "add" deserves to be there, I am not sure "apply" is.

git add is supposed to be rare, no?
That's why git commit lists file additions/removals ...

My list is typically
git checkout
git commit
git pull
git push
git rebase
git reset
git update-index

Maybe it makes sense to take the list from
"Main porcelain commands" section in git manual?

-- 
MST

```

## Junio C Hamano, 2007-06-25 07:48

Subject: Re: most commonly used git commands?
Message-ID: <7vodj41nm6.fsf@assigned-by-dhcp.pobox.com>
URL: https://gitlist.dev/e/7vodj41nm6.fsf%40assigned-by-dhcp.pobox.com
In-Reply-To: <20070625071752.GB15343@mellanox.co.il>

```
"Michael S. Tsirkin" <mst@dev.mellanox.co.il> writes:

>> Quoting Junio C Hamano <gitster@pobox.com>:
>> Perhaps they are most commonly used by the person who came up
>> with that list first ;-)?
>> 
>> I think "add" deserves to be there, I am not sure "apply" is.
>
> git add is supposed to be rare, no?
> That's why git commit lists file additions/removals ...

No.  You are talking in terms of pre-1.5 git.  The semantics of
"git add" has been clarified since then --- it adds contents,
and is not about telling git that there are new files it did not
know so far.

```

## Johannes Schindelin, 2007-06-25 07:51

Subject: Re: most commonly used git commands?
Message-ID: <Pine.LNX.4.64.0706250846200.4059@racer.site>
URL: https://gitlist.dev/e/Pine.LNX.4.64.0706250846200.4059%40racer.site
In-Reply-To: <20070625071752.GB15343@mellanox.co.il>

```
Hi,

On Mon, 25 Jun 2007, Michael S. Tsirkin wrote:

> Quoting Junio C Hamano <gitster@pobox.com>:
>
> > I think "add" deserves to be there, I am not sure "apply" is.
> 
> git add is supposed to be rare, no?

No.

> That's why git commit lists file additions/removals ...
> 
> My list is typically
> git checkout
> git commit
> git pull
> git push
> git rebase
> git reset
> git update-index

git update-index is really not user-friendly. That is why we have "git 
add". It is commonly used as a porcelain _instead of_ update-index.

FWIW your list is lacking log and diff, the two commands which are my top 
two. I do not use rebase all that often (before --interactive, that is). 
status, grep, mv, gc, show and branch are others I use quite often 
(although not as much as log and diff)

Ciao,
Dscho

```

## Josh Triplett, 2007-06-28 01:37

Subject: Re: most commonly used git commands?
Message-ID: <468310D4.2070504@freedesktop.org>
URL: https://gitlist.dev/e/468310D4.2070504%40freedesktop.org
In-Reply-To: <20070625064017.GA2839@mellanox.co.il>

```
Michael S. Tsirkin wrote:
> I did this by mistake:
> 
> $git fet linux-2.6
> git: 'fet' is not a git-command
> 
> The most commonly used git commands are:
>    add     Add file contents to the changeset to be committed next
>    apply   Apply a patch on a git index file and a working tree
> (use 'git help -a' to get a list of all installed git commands)

It should have listed more than just those two...

- Josh Triplett

```

## Martin Langhoff, 2007-06-28 02:17

Subject: Re: most commonly used git commands?
Message-ID: <46a038f90706271917j7abb4bddu21debafe3461c695@mail.gmail.com>
URL: https://gitlist.dev/e/46a038f90706271917j7abb4bddu21debafe3461c695%40mail.gmail.com
In-Reply-To: <7vodj41nm6.fsf@assigned-by-dhcp.pobox.com>

```
On 6/25/07, Junio C Hamano <gitster@pobox.com> wrote:
> "Michael S. Tsirkin" <mst@dev.mellanox.co.il> writes:
>
> >> Quoting Junio C Hamano <gitster@pobox.com>:
> >> Perhaps they are most commonly used by the person who came up
> >> with that list first ;-)?
> >>
> >> I think "add" deserves to be there, I am not sure "apply" is.
> >
> > git add is supposed to be rare, no?
> > That's why git commit lists file additions/removals ...
>
> No.  You are talking in terms of pre-1.5 git.  The semantics of
> "git add" has been clarified since then --- it adds contents,
> and is not about telling git that there are new files it did not
> know so far.

In other words - git-add is also a (semantically good) alias for
git-update-index.

So you "add" files to the next commit. Whether they are "new" to git
or just changed it doesn't matter that much in that situation. And
git-commit will look at those files that have been "added".

Makes things a whole lot easier to explain. I didn't understand it
initially, now I'm completely sold on the concept.


m

```

## Josh Triplett, 2007-06-28 02:30

Subject: Re: most commonly used git commands?
Message-ID: <46831D32.4090900@freedesktop.org>
URL: https://gitlist.dev/e/46831D32.4090900%40freedesktop.org
In-Reply-To: <46a038f90706271917j7abb4bddu21debafe3461c695@mail.gmail.com>

```
Martin Langhoff wrote:
> On 6/25/07, Junio C Hamano <gitster@pobox.com> wrote:
>> "Michael S. Tsirkin" <mst@dev.mellanox.co.il> writes:
>>>> Quoting Junio C Hamano <gitster@pobox.com>:
>>>> Perhaps they are most commonly used by the person who came up
>>>> with that list first ;-)?
>>>>
>>>> I think "add" deserves to be there, I am not sure "apply" is.
>>> git add is supposed to be rare, no?
>>> That's why git commit lists file additions/removals ...
>> No.  You are talking in terms of pre-1.5 git.  The semantics of
>> "git add" has been clarified since then --- it adds contents,
>> and is not about telling git that there are new files it did not
>> know so far.
> 
> In other words - git-add is also a (semantically good) alias for
> git-update-index.
> 
> So you "add" files to the next commit. Whether they are "new" to git
> or just changed it doesn't matter that much in that situation. And
> git-commit will look at those files that have been "added".
> 
> Makes things a whole lot easier to explain. I didn't understand it
> initially, now I'm completely sold on the concept.

Agreed; this change converted me from a "git commit -a" user to a big fan of
the index.

- Josh Triplett


```

## Alex Riesen, 2007-06-28 08:52

Subject: Re: most commonly used git commands?
Message-ID: <81b0412b0706280152g5cbd777y76757d9c608ea483@mail.gmail.com>
URL: https://gitlist.dev/e/81b0412b0706280152g5cbd777y76757d9c608ea483%40mail.gmail.com
In-Reply-To: <Pine.LNX.4.64.0706250846200.4059@racer.site>

```
On 6/25/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> git update-index is really not user-friendly. That is why we have "git
> add". It is commonly used as a porcelain _instead of_ update-index.

which reminds me: "git-add" lacks "--chmod=[+-]x".

```

## Johannes Schindelin, 2007-06-28 13:08

Subject: Re: most commonly used git commands?
Message-ID: <Pine.LNX.4.64.0706281408280.4438@racer.site>
URL: https://gitlist.dev/e/Pine.LNX.4.64.0706281408280.4438%40racer.site
In-Reply-To: <81b0412b0706280152g5cbd777y76757d9c608ea483@mail.gmail.com>

```
Hi,

On Thu, 28 Jun 2007, Alex Riesen wrote:

> On 6/25/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> > git update-index is really not user-friendly. That is why we have "git
> > add". It is commonly used as a porcelain _instead of_ update-index.
> 
> which reminds me: "git-add" lacks "--chmod=[+-]x".

???

Do you mean "chmod a+x blub && git add blub"?

Ciao,
Dscho

```

## Johannes Sixt, 2007-06-28 13:54

Subject: Re: most commonly used git commands?
Message-ID: <4683BDA5.996874EF@eudaptics.com>
URL: https://gitlist.dev/e/4683BDA5.996874EF%40eudaptics.com
In-Reply-To: <Pine.LNX.4.64.0706281408280.4438@racer.site>

```
Johannes Schindelin wrote:
> On Thu, 28 Jun 2007, Alex Riesen wrote:
> > On 6/25/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> > > git update-index is really not user-friendly. That is why we have "git
> > > add". It is commonly used as a porcelain _instead of_ update-index.
> >
> > which reminds me: "git-add" lacks "--chmod=[+-]x".
> 
> ???
> 
> Do you mean "chmod a+x blub && git add blub"?

No. It was meant as Alex said it. Windows (MinGW) doesn't understand
"chmod a+x blub".

-- Hannes

```

## Johannes Schindelin, 2007-06-28 14:07

Subject: Re: most commonly used git commands?
Message-ID: <Pine.LNX.4.64.0706281506390.4438@racer.site>
URL: https://gitlist.dev/e/Pine.LNX.4.64.0706281506390.4438%40racer.site
In-Reply-To: <4683BDA5.996874EF@eudaptics.com>

```


On Thu, 28 Jun 2007, Johannes Sixt wrote:

> Johannes Schindelin wrote:
> > On Thu, 28 Jun 2007, Alex Riesen wrote:
> > > On 6/25/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> > > > git update-index is really not user-friendly. That is why we have "git
> > > > add". It is commonly used as a porcelain _instead of_ update-index.
> > >
> > > which reminds me: "git-add" lacks "--chmod=[+-]x".
> > 
> > ???
> > 
> > Do you mean "chmod a+x blub && git add blub"?
> 
> No. It was meant as Alex said it. Windows (MinGW) doesn't understand
> "chmod a+x blub".

Yes, I suspected that. But I don't see a need for it on Windows (MinGW) to 
begin with.

Ciao,
Dscho

```

## Johannes Sixt, 2007-06-28 14:29

Subject: Re: most commonly used git commands?
Message-ID: <4683C5D2.FDF4ED02@eudaptics.com>
URL: https://gitlist.dev/e/4683C5D2.FDF4ED02%40eudaptics.com
In-Reply-To: <Pine.LNX.4.64.0706281506390.4438@racer.site>

```
Johannes Schindelin wrote:
> 
> On Thu, 28 Jun 2007, Johannes Sixt wrote:
> > No. It was meant as Alex said it. Windows (MinGW) doesn't understand
> > "chmod a+x blub".
> 
> Yes, I suspected that. But I don't see a need for it on Windows (MinGW) to
> begin with.

True for Windows-centered projects. But for cross-platform projects
--chmod=+x is needed every now and then.

AFAIAC, it's alright to fall back to update-index for those occasions,
even though they are not that rare due to a deficiency of
merge-recursive: When it merges an executable file, it loses the +x bit,
even if core.filemode=false!

-- Hannes

```

## Johannes Sixt, 2007-06-28 14:49

Subject: Re: most commonly used git commands?
Message-ID: <4683CA7A.7F8070D7@eudaptics.com>
URL: https://gitlist.dev/e/4683CA7A.7F8070D7%40eudaptics.com
In-Reply-To: <4683C5D2.FDF4ED02@eudaptics.com>

```
Johannes Sixt wrote:
> AFAIAC, it's alright to fall back to update-index for those occasions,
> even though they are not that rare due to a deficiency of
> merge-recursive: When it merges an executable file, it loses the +x bit,
> even if core.filemode=false!

I take that back.

The deficiency is not in merge-recursive, but in 'git add'. The problem
is that after a conflicted merge of an executable file 'git add' loses
the +x bit even if core.filemode=false.

-- Hannes

```

## Johannes Schindelin, 2007-06-28 17:02

Subject: [PATCH] git add: respect core.filemode even with unmerged entries in the index
Message-ID: <Pine.LNX.4.64.0706281653260.4438@racer.site>
URL: https://gitlist.dev/e/Pine.LNX.4.64.0706281653260.4438%40racer.site
In-Reply-To: <4683CA7A.7F8070D7@eudaptics.com>

```

When a merge left unmerged entries, git add failed to pick up the
file mode from the index, when core.filemode == 0.

Noticed by Johannes Sixt.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---

	On Thu, 28 Jun 2007, Johannes Sixt wrote:

	> Johannes Sixt wrote:
	> 
	> The deficiency is not in merge-recursive, but in 'git add'. The 
	> problem is that after a conflicted merge of an executable file 
	> 'git add' loses the +x bit even if core.filemode=false.

	How's that?

 read-cache.c   |    6 ++++++
 t/t3700-add.sh |   14 ++++++++++++++
 2 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/read-cache.c b/read-cache.c
index 4362b11..a74e4a7 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -382,6 +382,12 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
 		struct cache_entry *ent;
 		int pos = index_name_pos(istate, path, namelen);
 
+		/* might be unmerged */
+		if (pos < 0 && 1-pos < istate->cache_nr &&
+				namelen == ce_namelen(istate->cache[1-pos]) &&
+				!memcmp(path, istate->cache[1-pos]->name,
+					namelen))
+			pos = 1-pos;
 		ent = (0 <= pos) ? istate->cache[pos] : NULL;
 		ce->ce_mode = ce_mode_from_stat(ent, st.st_mode);
 	}
diff --git a/t/t3700-add.sh b/t/t3700-add.sh
index ad8cc7d..d75970b 100755
--- a/t/t3700-add.sh
+++ b/t/t3700-add.sh
@@ -110,4 +110,18 @@ test_expect_success 'check correct prefix detection' '
 	git add 1/2/a 1/3/b 1/2/c
 '
 
+test_expect_success 'git add and filemode=0 with unmerged entries' '
+	echo 1 > stage1 &&
+	echo 2 > stage2 &&
+	echo 3 > stage3 &&
+	for s in 1 2 3
+	do
+		echo "100755 $(git hash-object -w stage$s) $s	file"
+	done | git update-index --index-info &&
+	git config core.filemode 0 &&
+	echo new > file &&
+	git add file &&
+	git ls-files --stage | grep "^100755 .* 0	file$"
+'
+
 test_done
-- 
1.5.2.2.3228.g16a27

```

## Johannes Sixt, 2007-06-29 06:57

Subject: Re: [PATCH] git add: respect core.filemode even with unmerged entriesin the index
Message-ID: <4684AD41.9868C32F@eudaptics.com>
URL: https://gitlist.dev/e/4684AD41.9868C32F%40eudaptics.com
In-Reply-To: <Pine.LNX.4.64.0706281653260.4438@racer.site>

```
Johannes Schindelin wrote:
> 
> When a merge left unmerged entries, git add failed to pick up the
> file mode from the index, when core.filemode == 0.
> 
> Noticed by Johannes Sixt.
> 
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
> 
>         On Thu, 28 Jun 2007, Johannes Sixt wrote:
> 
>         > Johannes Sixt wrote:
>         >
>         > The deficiency is not in merge-recursive, but in 'git add'. The
>         > problem is that after a conflicted merge of an executable file
>         > 'git add' loses the +x bit even if core.filemode=false.
> 
>         How's that?

That's fine, thanks.

It covers the most common case that all three stages are in the index.
However, if only two stages are present, the file mode is still taken
from the file instead of from the index. As that easy to solve (at least
for the unambiguous case)?

-- Hannes

```

## Junio C Hamano, 2007-06-29 08:36

Subject: Re: [PATCH] git add: respect core.filemode even with unmerged entries in the index
Message-ID: <7vir97f98o.fsf@assigned-by-dhcp.pobox.com>
URL: https://gitlist.dev/e/7vir97f98o.fsf%40assigned-by-dhcp.pobox.com
In-Reply-To: <Pine.LNX.4.64.0706281653260.4438@racer.site>

```
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> diff --git a/read-cache.c b/read-cache.c
> index 4362b11..a74e4a7 100644
> --- a/read-cache.c
> +++ b/read-cache.c
> @@ -382,6 +382,12 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
>  		struct cache_entry *ent;
>  		int pos = index_name_pos(istate, path, namelen);
>  
> +		/* might be unmerged */
> +		if (pos < 0 && 1-pos < istate->cache_nr &&
> +				namelen == ce_namelen(istate->cache[1-pos]) &&
> +				!memcmp(path, istate->cache[1-pos]->name,
> +					namelen))
> +			pos = 1-pos;
>  		ent = (0 <= pos) ? istate->cache[pos] : NULL;
>  		ce->ce_mode = ce_mode_from_stat(ent, st.st_mode);
>  	}

Hmph.

 * Are you sure about (1-pos)?

 * I _think_ we would want to favor our stage (i.e. #2) when
   unmerged, over other stages.  Perhaps like this:

	if (pos < 0) {
        	int a_pos = -1, our_pos = -1;
		pos = -pos-1;
		while ((pos < istate->cache_nr) &&
			namelen == ce_namelen(istate->cache[pos]) &&
			!memcmp(path, istate->cache[pos]->name, namelen))
			if (a_pos < 0)
                        	a_pos = pos;
                        if (ce_stage(istate->cache[pos]) == 2)
                        	our_pos = pos;
			pos++;
                }
		if (our_pos >= 0)
                	pos = our_pos;
		else if (a_pos >= 0)
                	pos = a_pos;
		else
                	pos = -1;
	}
	ent = (0 <= pos) ? istate->cache[pos] : NULL;
	ce->ce_mode = ce_mode_from_stat(ent, st.st_mode);

```

## Johannes Schindelin, 2007-06-29 10:06

Subject: Re: [PATCH] git add: respect core.filemode even with unmerged entries in the index
Message-ID: <Pine.LNX.4.64.0706291103470.4438@racer.site>
URL: https://gitlist.dev/e/Pine.LNX.4.64.0706291103470.4438%40racer.site
In-Reply-To: <7vir97f98o.fsf@assigned-by-dhcp.pobox.com>

```
Hi,

On Fri, 29 Jun 2007, Junio C Hamano wrote:

> Hmph.
> 
>  * Are you sure about (1-pos)?
> 
>  * I _think_ we would want to favor our stage (i.e. #2)

Hmph back.

I _thought_ that our stage is #1, not even bothering to check the 
documentation. But it seems that you are right.

So your code looks fine to me, except that I would move the whole 
get_index_entry_for_file_even_if_the_entry_is_unmerged(name, namelen) 
code into its own function.

Want me to prepare a patch? If so, I'll do it tonight, since I will be 
occupied the rest of the (working) day.

Ciao,
Dscho

```

## Johannes Schindelin, 2007-06-29 10:07

Subject: Re: [PATCH] git add: respect core.filemode even with unmerged entriesin the index
Message-ID: <Pine.LNX.4.64.0706291106190.4438@racer.site>
URL: https://gitlist.dev/e/Pine.LNX.4.64.0706291106190.4438%40racer.site
In-Reply-To: <4684AD41.9868C32F@eudaptics.com>

```
Hi,

On Fri, 29 Jun 2007, Johannes Sixt wrote:

> However, if only two stages are present, the file mode is still taken 
> from the file instead of from the index. As that easy to solve (at least 
> for the unambiguous case)?

It might be related to the bug Junio found, i.e. that I assumed stage 1 to 
be "ours".

Ciao,
Dscho

```

## Junio C Hamano, 2007-06-29 10:20

Subject: Re: [PATCH] git add: respect core.filemode even with unmerged entriesin the index
Message-ID: <7v3b0bf4ea.fsf@assigned-by-dhcp.pobox.com>
URL: https://gitlist.dev/e/7v3b0bf4ea.fsf%40assigned-by-dhcp.pobox.com
In-Reply-To: <Pine.LNX.4.64.0706291106190.4438@racer.site>

```
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> On Fri, 29 Jun 2007, Johannes Sixt wrote:
>
>> However, if only two stages are present, the file mode is still taken 
>> from the file instead of from the index. As that easy to solve (at least 
>> for the unambiguous case)?
>
> It might be related to the bug Junio found, i.e. that I assumed stage 1 to 
> be "ours".

Actually it is because (-1-pos) and (1-pos) are two apart.  By
starting to scan from (1-pos), you are jumping directly to
either the next path (in which case you do not pick it up), or
"their" version (i.e. stage #3) iff there are three stages for
the path in question.

I am all for refactoring the funny "pick up an existing entry at
any stage, but favor 0 then 2 then 1 and finally 3" into a
separate function.  It makes sense, although I do not offhand
know of a place that we can immediately reuse it (logically,
diff-files ought to do that, but I haven't checked).

```

## Johannes Schindelin, 2007-06-29 17:32

Subject: [PATCH] git add: respect core.filemode with unmerged entries
Message-ID: <Pine.LNX.4.64.0706291820200.4438@racer.site>
URL: https://gitlist.dev/e/Pine.LNX.4.64.0706291820200.4438%40racer.site
In-Reply-To: <7v3b0bf4ea.fsf@assigned-by-dhcp.pobox.com>

```

When a merge left unmerged entries, git add failed to pick up the
file mode from the index, when core.filemode == 0. If more than one
unmerged entry is there, the order of stage preference is 2, 1, 3.

Noticed by Johannes Sixt.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---

	On Fri, 29 Jun 2007, Junio C Hamano wrote:

	> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
	> 
	> > On Fri, 29 Jun 2007, Johannes Sixt wrote:
	> >
	> >> However, if only two stages are present, the file mode is 
	> >> still taken from the file instead of from the index. As that 
	> >> easy to solve (at least for the unambiguous case)?
	> >
	> > It might be related to the bug Junio found, i.e. that I assumed stage 1 to 
	> > be "ours".
	> 
	> Actually it is because (-1-pos) and (1-pos) are two apart.

	I congratulate myself. My first off-by-two bug.

	> I am all for refactoring the funny "pick up an existing entry at
	> any stage, but favor 0 then 2 then 1 and finally 3" into a
	> separate function.  It makes sense, although I do not offhand
	> know of a place that we can immediately reuse it (logically,
	> diff-files ought to do that, but I haven't checked).

	Me neither. But at least I coded it (hopefully) correctly this 
	time, even accompied it by a test verifying that I got it right.

 read-cache.c   |   30 +++++++++++++++++++++++++++++-
 t/t3700-add.sh |   26 ++++++++++++++++++++++++++
 2 files changed, 55 insertions(+), 1 deletions(-)

diff --git a/read-cache.c b/read-cache.c
index 4362b11..a363f31 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -350,6 +350,34 @@ int remove_file_from_index(struct index_state *istate, const char *path)
 	return 0;
 }
 
+static int compare_name(struct cache_entry *ce, const char *path, int namelen)
+{
+	return namelen != ce_namelen(ce) || memcmp(path, ce->name, namelen);
+}
+
+static int index_name_pos_also_unmerged(struct index_state *istate,
+	const char *path, int namelen)
+{
+	int pos = index_name_pos(istate, path, namelen);
+	struct cache_entry *ce;
+
+	if (pos >= 0)
+		return pos;
+
+	/* maybe unmerged? */
+	pos = -1 - pos;
+	if (pos >= istate->cache_nr ||
+			compare_name((ce = istate->cache[pos]), path, namelen))
+		return -1;
+
+	/* order of preference: stage 2, 1, 3 */
+	if (ce_stage(ce) == 1 && pos + 1 < istate->cache_nr &&
+			ce_stage((ce = istate->cache[pos + 1])) == 2 &&
+			!compare_name(ce, path, namelen))
+		pos++;
+	return pos;
+}
+
 int add_file_to_index(struct index_state *istate, const char *path, int verbose)
 {
 	int size, namelen;
@@ -380,7 +408,7 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
 		 * from it, otherwise assume unexecutable regular file.
 		 */
 		struct cache_entry *ent;
-		int pos = index_name_pos(istate, path, namelen);
+		int pos = index_name_pos_also_unmerged(istate, path, namelen);
 
 		ent = (0 <= pos) ? istate->cache[pos] : NULL;
 		ce->ce_mode = ce_mode_from_stat(ent, st.st_mode);
diff --git a/t/t3700-add.sh b/t/t3700-add.sh
index ad8cc7d..0d80c6a 100755
--- a/t/t3700-add.sh
+++ b/t/t3700-add.sh
@@ -110,4 +110,30 @@ test_expect_success 'check correct prefix detection' '
 	git add 1/2/a 1/3/b 1/2/c
 '
 
+test_expect_success 'git add and filemode=0 with unmerged entries' '
+	echo 1 > stage1 &&
+	echo 2 > stage2 &&
+	echo 3 > stage3 &&
+	for s in 1 2 3
+	do
+		echo "100755 $(git hash-object -w stage$s) $s	file"
+	done | git update-index --index-info &&
+	git config core.filemode 0 &&
+	echo new > file &&
+	git add file &&
+	git ls-files --stage | grep "^100755 .* 0	file$"
+'
+
+test_expect_success 'git add and filemode=0 prefers stage 2 over stage 1' '
+	git rm --cached -f file &&
+	(
+		echo "100644 $(git hash-object -w stage1) 1	file"
+		echo "100755 $(git hash-object -w stage2) 2	file"
+	) | git update-index --index-info &&
+	git config core.filemode 0 &&
+	echo new > file &&
+	git add file &&
+	git ls-files --stage | grep "^100755 .* 0	file$"
+'
+
 test_done
-- 
1.5.2.2.3228.g16a27

```

## Alex Riesen, 2007-06-30 13:14

Subject: Re: most commonly used git commands?
Message-ID: <20070630131428.GA2866@steel.home>
URL: https://gitlist.dev/e/20070630131428.GA2866%40steel.home
In-Reply-To: <Pine.LNX.4.64.0706281506390.4438@racer.site>

```
Johannes Schindelin, Thu, Jun 28, 2007 16:07:17 +0200:
> > No. It was meant as Alex said it. Windows (MinGW) doesn't understand
> > "chmod a+x blub".
> 
> Yes, I suspected that. But I don't see a need for it on Windows (MinGW) to 
> begin with.
> 

But it is necessary on Windows (Cygwin): chmod(2) with mode set to
0644 will happily take execute permission from an .com, .bat, .cmd,
.pl, .exe or .dll file. Which means something different on Windows,
but results in unexpectedly (for a Windows user) looking errors. The
users there do not expect seeing an .exe-file but be not able to
run it.

```

## Johannes Schindelin, 2007-06-30 14:31

Subject: Re: most commonly used git commands?
Message-ID: <Pine.LNX.4.64.0706301531050.4438@racer.site>
URL: https://gitlist.dev/e/Pine.LNX.4.64.0706301531050.4438%40racer.site
In-Reply-To: <20070630131428.GA2866@steel.home>

```
Hi,

On Sat, 30 Jun 2007, Alex Riesen wrote:

> Johannes Schindelin, Thu, Jun 28, 2007 16:07:17 +0200:
> > > No. It was meant as Alex said it. Windows (MinGW) doesn't understand
> > > "chmod a+x blub".
> > 
> > Yes, I suspected that. But I don't see a need for it on Windows (MinGW) to 
> > begin with.
> > 
> 
> But it is necessary on Windows (Cygwin):

I thought that on Cygwin, filemode=1? I mean, Cygwin _never_ had problems 
with chmod under my fingers.

Ciao,
Dscho

```

## Alex Riesen, 2007-06-30 22:35

Subject: Re: most commonly used git commands?
Message-ID: <20070630223504.GB2703@steel.home>
URL: https://gitlist.dev/e/20070630223504.GB2703%40steel.home
In-Reply-To: <Pine.LNX.4.64.0706301531050.4438@racer.site>

```
Johannes Schindelin, Sat, Jun 30, 2007 16:31:48 +0200:
> On Sat, 30 Jun 2007, Alex Riesen wrote:
> > Johannes Schindelin, Thu, Jun 28, 2007 16:07:17 +0200:
> > > > No. It was meant as Alex said it. Windows (MinGW) doesn't understand
> > > > "chmod a+x blub".
> > > 
> > > Yes, I suspected that. But I don't see a need for it on Windows (MinGW) to 
> > > begin with.
> > > 
> > 
> > But it is necessary on Windows (Cygwin):
> 
> I thought that on Cygwin, filemode=1? I mean, Cygwin _never_ had problems 
> with chmod under my fingers.
> 

Try doing stat(2) on file.txt which contains "#!/bin/sh" in its first
line and for which you have issued a chmod yet. Like a new file, or
like every file in a git-tracked directory after you did a fresh
checkout. Cygwin actually opens the files when doing stat(2), looks
inside and tries to guess if they are executable.

You should have said: "Cygwin _never_ had problems with chmod because
it cannot and didn't make it work". It is not just chmod, the other
side, stat, matters as well.

```

## Jan Hudec, 2007-07-01 09:16

Subject: Re: most commonly used git commands?
Message-ID: <20070701091645.GA26243@efreet.light.src>
URL: https://gitlist.dev/e/20070701091645.GA26243%40efreet.light.src
In-Reply-To: <20070630223504.GB2703@steel.home>

```
On Sun, Jul 01, 2007 at 00:35:04 +0200, Alex Riesen wrote:
> Johannes Schindelin, Sat, Jun 30, 2007 16:31:48 +0200:
> > On Sat, 30 Jun 2007, Alex Riesen wrote:
> > > Johannes Schindelin, Thu, Jun 28, 2007 16:07:17 +0200:
> > > > > No. It was meant as Alex said it. Windows (MinGW) doesn't understand
> > > > > "chmod a+x blub".
> > > > 
> > > > Yes, I suspected that. But I don't see a need for it on Windows (MinGW) to 
> > > > begin with.
> > > > 
> > > 
> > > But it is necessary on Windows (Cygwin):
> > 
> > I thought that on Cygwin, filemode=1? I mean, Cygwin _never_ had problems 
> > with chmod under my fingers.
> > 
> 
> Try doing stat(2) on file.txt which contains "#!/bin/sh" in its first
> line and for which you have issued a chmod yet. Like a new file, or
> like every file in a git-tracked directory after you did a fresh
> checkout. Cygwin actually opens the files when doing stat(2), looks
> inside and tries to guess if they are executable.
> 
> You should have said: "Cygwin _never_ had problems with chmod because
> it cannot and didn't make it work". It is not just chmod, the other
> side, stat, matters as well.

I always had the impression, that cygwin actually *implements* chmod and does
so using windows ACLs. And in ACL windows *do* support executable bit (I
copied some DLL with cygwin copy and it was NOT executable then). Of course
this only works on filesystems (NTFS, NTFS exported over CIFS) that support
ACLs. On FAT it might be doing something like you describe. Though it is
mostly irrelevant for git, because git does not work on FAT (Cygwin only
supports posix rename on NTFS).

-- 
						 Jan 'Bulb' Hudec <bulb@ucw.cz>

```

## Alex Riesen, 2007-07-01 16:49

Subject: Re: most commonly used git commands?
Message-ID: <20070701164901.GB3661@steel.home>
URL: https://gitlist.dev/e/20070701164901.GB3661%40steel.home
In-Reply-To: <20070701091645.GA26243@efreet.light.src>

```
Jan Hudec, Sun, Jul 01, 2007 11:16:46 +0200:
> On Sun, Jul 01, 2007 at 00:35:04 +0200, Alex Riesen wrote:
> > Johannes Schindelin, Sat, Jun 30, 2007 16:31:48 +0200:
> > > On Sat, 30 Jun 2007, Alex Riesen wrote:
> > > > Johannes Schindelin, Thu, Jun 28, 2007 16:07:17 +0200:
> > > > > > No. It was meant as Alex said it. Windows (MinGW) doesn't understand
> > > > > > "chmod a+x blub".
> > > > > 
> > > > > Yes, I suspected that. But I don't see a need for it on Windows (MinGW) to 
> > > > > begin with.
> > > > > 
> > > > 
> > > > But it is necessary on Windows (Cygwin):
> > > 
> > > I thought that on Cygwin, filemode=1? I mean, Cygwin _never_ had problems 
> > > with chmod under my fingers.
> > > 
> > 
> > Try doing stat(2) on file.txt which contains "#!/bin/sh" in its first
> > line and for which you have issued a chmod yet. Like a new file, or
> > like every file in a git-tracked directory after you did a fresh
> > checkout. Cygwin actually opens the files when doing stat(2), looks
> > inside and tries to guess if they are executable.
> > 
> > You should have said: "Cygwin _never_ had problems with chmod because
> > it cannot and didn't make it work". It is not just chmod, the other
> > side, stat, matters as well.
> 
> I always had the impression, that cygwin actually *implements* chmod and does
> so using windows ACLs. And in ACL windows *do* support executable bit (I

Windows ACLs don't have exec bit in the UNIX sense.

> copied some DLL with cygwin copy and it was NOT executable then). Of course
> this only works on filesystems (NTFS, NTFS exported over CIFS) that support
> ACLs. On FAT it might be doing something like you describe. Though it is
> mostly irrelevant for git, because git does not work on FAT (Cygwin only
> supports posix rename on NTFS).

It does not work on NTFS either. For all the same reason I described
above: Cygwin tries to be clever (and annoying) and looks into files.
And no Windows program (like, for example, your editor of preference)
will call Cygwin's chmod just to set the permissions how Cygwin likes
them.

```
