# conflict status

8 messages from 2009-08-03 to 2009-08-04. Participants: Michael Wild, Sverre Rabbelier, Thomas Rast, Junio C Hamano, Jakub Narebski.
Thread: https://gitlist.dev/t/20355

## Michael Wild, 2009-08-03 15:14

Subject: conflict status
Message-ID: <DDAD985F-C9CA-4159-B382-354D4B082C19@users.sourceforge.net>
URL: https://gitlist.dev/e/DDAD985F-C9CA-4159-B382-354D4B082C19%40users.sourceforge.net

```
Hi all

I'm merging two branches with a large number of conflicts.  
Fortunately, there are many modified/deleted conflicts (locally  
modified, remotely deleted), and I know that for those I want to pick  
the deleted version. However, I can't seem to motivate GIT into  
telling me for which of the conflicting files this is the case. I know  
that git-mergetool somehow extracts this information, but looking at  
the code, it seems to me that there must be an easier, user-level  
method of obtaining this information.

Generally speaking, I would like to know for each file with a conflict  
what it's status is, similar to what SVN does:
- locally modified/created/deleted/...
- remotely modified/created/deleted/...

Please excuse me if this is either trivial or has been answered many  
times before, but neither perusing the man-pages, nor asking google  
turned up anything remotely useful.

Thanks for the help

Michael

```

## Sverre Rabbelier, 2009-08-03 17:37

Subject: Re: conflict status
Message-ID: <fabb9a1e0908031037t16a828f6h4de9fb11bcc957fe@mail.gmail.com>
URL: https://gitlist.dev/e/fabb9a1e0908031037t16a828f6h4de9fb11bcc957fe%40mail.gmail.com
In-Reply-To: <DDAD985F-C9CA-4159-B382-354D4B082C19@users.sourceforge.net>

```
Heya,

On Mon, Aug 3, 2009 at 08:14, Michael Wild<themiwi@users.sourceforge.net> wrote:
> Generally speaking, I would like to know for each file with a conflict what
> it's status is, similar to what SVN does:
> - locally modified/created/deleted/...
> - remotely modified/created/deleted/...

Try 'git status' :),

-- 
Cheers,

Sverre Rabbelier

```

## Thomas Rast, 2009-08-03 18:17

Subject: Re: conflict status
Message-ID: <200908032017.35101.trast@student.ethz.ch>
URL: https://gitlist.dev/e/200908032017.35101.trast%40student.ethz.ch
In-Reply-To: <fabb9a1e0908031037t16a828f6h4de9fb11bcc957fe@mail.gmail.com>

```
You wrote:
> Heya,
> 
> On Mon, Aug 3, 2009 at 08:14, Michael Wild<themiwi@users.sourceforge.net> wrote:
> > Generally speaking, I would like to know for each file with a conflict what
> > it's status is, similar to what SVN does:
> > - locally modified/created/deleted/...
> > - remotely modified/created/deleted/...
> 
> Try 'git status' :),

That only shows 'unmerged: foo' for me...

The closest to porcelain I can get while still having all the
information is

  $ git ls-files -s foo
  100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 1       foo
  100644 d00491fd7e5bb6fa28c517a0bb32b8b506539d4d 2       foo

In other words, not porcelain at all.

The third column is the stage: 1 for base, 2 for ours, 3 for theirs.
So the above means that the file was changed between base and ours,
and removed between base and theirs (as the entry is missing).

-- 
Thomas Rast
trast@{inf,student}.ethz.ch

```

## Junio C Hamano, 2009-08-03 18:35

Subject: Re: conflict status
Message-ID: <7vvdl4925k.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vvdl4925k.fsf%40alter.siamese.dyndns.org
In-Reply-To: <200908032017.35101.trast@student.ethz.ch>

```
Thomas Rast <trast@student.ethz.ch> writes:

> That only shows 'unmerged: foo' for me...
>
> The closest to porcelain I can get while still having all the
> information is
>
>   $ git ls-files -s foo
>   100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 1       foo
>   100644 d00491fd7e5bb6fa28c517a0bb32b8b506539d4d 2       foo
>
> In other words, not porcelain at all.

"git ls-files -u" would be what you want.  It shows all the paths with
conflicts in the index, and omits paths without conflicts in the index.
And the object names allow you to inspect the individual stages.

```

## Michael Wild, 2009-08-04 07:10

Subject: Re: conflict status
Message-ID: <4F52523A-2CEA-4CD3-A094-A2627E2A4403@users.sourceforge.net>
URL: https://gitlist.dev/e/4F52523A-2CEA-4CD3-A094-A2627E2A4403%40users.sourceforge.net
In-Reply-To: <7vvdl4925k.fsf@alter.siamese.dyndns.org>

```

On 3. Aug, 2009, at 20:35, Junio C Hamano wrote:

> Thomas Rast <trast@student.ethz.ch> writes:
>
>> That only shows 'unmerged: foo' for me...
>>
>> The closest to porcelain I can get while still having all the
>> information is
>>
>>  $ git ls-files -s foo
>>  100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 1       foo
>>  100644 d00491fd7e5bb6fa28c517a0bb32b8b506539d4d 2       foo
>>
>> In other words, not porcelain at all.
>
> "git ls-files -u" would be what you want.  It shows all the paths with
> conflicts in the index, and omits paths without conflicts in the  
> index.
> And the object names allow you to inspect the individual stages.
>


I found out about that one too (by having a look at git-mergetool),  
and came up with the following quick hack (doesn't take any arguments/ 
options, is very rough and slow for a large number of conflicts). For  
each unmerged file it displays the file name, prefixed with the local  
and remote state. Possible states are "c" for created, "m" for  
modified and "d" for deleted. Probably there are other cases I'm not  
aware of and require special handling.

#!/bin/sh
# displays the merge status of files

# TODO all the niceties, bells and whistles...
USAGE=''
# requires PWD to be top-level
unset SUBDIRECTORY_OK
  . "$(git --exec-path)/git-sh-setup"
# obviously...
require_work_tree

# describe the state (deleted, modified or created)
describe_state () {
   mode="$1"

   if test -z "$mode"; then
     printf "d "
   else
     if test -n "$base_mode"; then
       printf "m "
     else
       printf "c "
     fi
   fi
}

# get all conflicts
conflicts="$(git-status | awk '/unmerged:/{print $3;next}')"

for f in $conflicts; do
   # extract the file mode for base, local and remote
   base_mode=$(git ls-files -u -- "$f" | awk '{if ($3==1) print $1;}')
   local_mode=$(git ls-files -u -- "$f" | awk '{if ($3==2) print $1;}')
   remote_mode=$(git ls-files -u -- "$f" | awk '{if ($3==3) print $1;}')
   # create the status flags
   describe_state "$local_mode"
   describe_state "$remote_mode"
   # append the file name
   echo " $f"
done

```

## Jakub Narebski, 2009-08-04 07:19

Subject: Re: conflict status
Message-ID: <m34osoqc5p.fsf@localhost.localdomain>
URL: https://gitlist.dev/e/m34osoqc5p.fsf%40localhost.localdomain
In-Reply-To: <4F52523A-2CEA-4CD3-A094-A2627E2A4403@users.sourceforge.net>

```
Michael Wild <themiwi@users.sourceforge.net> writes:
> On 3. Aug, 2009, at 20:35, Junio C Hamano wrote:
>> Thomas Rast <trast@student.ethz.ch> writes:
>>
>>> That only shows 'unmerged: foo' for me...
>>>
>>> The closest to porcelain I can get while still having all the
>>> information is
>>>
>>>  $ git ls-files -s foo
>>>  100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 1       foo
>>>  100644 d00491fd7e5bb6fa28c517a0bb32b8b506539d4d 2       foo
>>>
>>> In other words, not porcelain at all.
>>
>> "git ls-files -u" would be what you want.  It shows all the paths with
>> conflicts in the index, and omits paths without conflicts in the
>> index.
>>
>> And the object names allow you to inspect the individual stages.
>>
> 
> 
> I found out about that one too (by having a look at git-mergetool),
> and came up with the following quick hack (doesn't take any arguments/
> options, is very rough and slow for a large number of conflicts). For
> each unmerged file it displays the file name, prefixed with the local
> and remote state. Possible states are "c" for created, "m" for
> modified and "d" for deleted. Probably there are other cases I'm not
> aware of and require special handling.

If you don't need SHA-1s, why not use -t or -v option of git-ls-files,
e.g.:

  $ git ls-files -v -u

-- 
Jakub Narebski
Poland
ShadeHawk on #git

```

## Michael Wild, 2009-08-04 07:31

Subject: Re: conflict status
Message-ID: <398EA050-EEC9-4C16-8225-410BBECABB13@users.sourceforge.net>
URL: https://gitlist.dev/e/398EA050-EEC9-4C16-8225-410BBECABB13%40users.sourceforge.net
In-Reply-To: <m34osoqc5p.fsf@localhost.localdomain>

```

On 4. Aug, 2009, at 9:19, Jakub Narebski wrote:
>
> If you don't need SHA-1s, why not use -t or -v option of git-ls-files,
> e.g.:
>
>  $ git ls-files -v -u
>


Huh? Sorry, I don't get your point. -v and -t will just prefix a  
"M" (or sometimes "m" in the case of-v) for unmerged files. But I  
already know they are unmerged, so why bother?

```

## Junio C Hamano, 2009-08-04 07:56

Subject: Re: conflict status
Message-ID: <7vhbwoypu4.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vhbwoypu4.fsf%40alter.siamese.dyndns.org
In-Reply-To: <4F52523A-2CEA-4CD3-A094-A2627E2A4403@users.sourceforge.net>

```
Michael Wild <themiwi@users.sourceforge.net> writes:

> # get all conflicts
> conflicts="$(git-status | awk '/unmerged:/{print $3;next}')"
>
> for f in $conflicts; do
>   # extract the file mode for base, local and remote
>   base_mode=$(git ls-files -u -- "$f" | awk '{if ($3==1) print $1;}')
>   local_mode=$(git ls-files -u -- "$f" | awk '{if ($3==2) print $1;}')
>   remote_mode=$(git ls-files -u -- "$f" | awk '{if ($3==3) print $1;}')
>   # create the status flags
>   describe_state "$local_mode"
>   describe_state "$remote_mode"
>   # append the file name
>   echo " $f"
> done

Looks an awfully inefficient way to say "git ls-files -u" to me.  If you
do not see stage 2, you do not have it.  If you do not see stage 3, they
do not have it.

If you really really want to condense the object name information out, you
could do something like this.

-- >8 --
#!/bin/sh
git ls-files -u -z |
perl -e '
	$/ = "\0";
        my ($last_path, @stage);
        sub describe_mode {
        	my $ours = $_[0];
		my $sign;
                if (!defined $ours) {
                	$sign = "d";
		} elsif (defined $stage[1]) {
                	$sign = "m";
		} else {
			$sign = "c";
                }
		return $sign;
        }
	sub flush_path {
        	printf("%s %s %s\n",
                	describe_mode($stage[2]),
                	describe_mode($stage[3]),
			$last_path);
		$last_path = undef;
        	@stage = ();
        }
        while (<>) {
		chomp;
        	my ($mode, $sha1, $stage, $path) =
                	/^([0-7]+) ([0-9a-f]{40}) ([1-3])\t(.*)$/;
		if (defined $last_path) {
			flush_path() if ($path ne $last_path);
                }
                $stage[$stage] = 1;
                $last_path = $path;
	}
        if (defined $last_path) {
                flush_path() if ($path ne $last_path);
        }
'
-- 8< --

I however do not think it is all that interesting, though.

```
