Revision 2501aff8b7516115c409cb34cc50305cdde40a47 authored by Jeff King on 28 September 2013, 08:31:45 UTC, committed by Jonathan Nieder on 14 October 2013, 23:55:13 UTC
When we are handling a curl response code in http_request or
in the remote-curl RPC code, we use the handle_curl_result
helper to translate curl's response into an easy-to-use
code. When we see an HTTP 401, we do one of two things:

  1. If we already had a filled-in credential, we mark it as
     rejected, and then return HTTP_NOAUTH to indicate to
     the caller that we failed.

  2. If we didn't, then we ask for a new credential and tell
     the caller HTTP_REAUTH to indicate that they may want
     to try again.

Rejecting in the first case makes sense; it is the natural
result of the request we just made. However, prompting for
more credentials in the second step does not always make
sense. We do not know for sure that the caller is going to
make a second request, and nor are we sure that it will be
to the same URL. Logically, the prompt belongs not to the
request we just finished, but to the request we are (maybe)
about to make.

In practice, it is very hard to trigger any bad behavior.
Currently, if we make a second request, it will always be to
the same URL (even in the face of redirects, because curl
handles the redirects internally). And we almost always
retry on HTTP_REAUTH these days. The one exception is if we
are streaming a large RPC request to the server (e.g., a
pushed packfile), in which case we cannot restart. It's
extremely unlikely to see a 401 response at this stage,
though, as we would typically have seen it when we sent a
probe request, before streaming the data.

This patch drops the automatic prompt out of case 2, and
instead requires the caller to do it. This is a few extra
lines of code, and the bug it fixes is unlikely to come up
in practice. But it is conceptually cleaner, and paves the
way for better handling of credentials across redirects.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
1 parent 1bbcc22
Raw File
diff-format.txt
Raw output format
-----------------

The raw output format from "git-diff-index", "git-diff-tree",
"git-diff-files" and "git diff --raw" are very similar.

These commands all compare two sets of things; what is
compared differs:

git-diff-index <tree-ish>::
        compares the <tree-ish> and the files on the filesystem.

git-diff-index --cached <tree-ish>::
        compares the <tree-ish> and the index.

git-diff-tree [-r] <tree-ish-1> <tree-ish-2> [<pattern>...]::
        compares the trees named by the two arguments.

git-diff-files [<pattern>...]::
        compares the index and the files on the filesystem.

The "git-diff-tree" command begins its output by printing the hash of
what is being compared. After that, all the commands print one output
line per changed file.

An output line is formatted this way:

------------------------------------------------
in-place edit  :100644 100644 bcd1234... 0123456... M file0
copy-edit      :100644 100644 abcd123... 1234567... C68 file1 file2
rename-edit    :100644 100644 abcd123... 1234567... R86 file1 file3
create         :000000 100644 0000000... 1234567... A file4
delete         :100644 000000 1234567... 0000000... D file5
unmerged       :000000 000000 0000000... 0000000... U file6
------------------------------------------------

That is, from the left to the right:

. a colon.
. mode for "src"; 000000 if creation or unmerged.
. a space.
. mode for "dst"; 000000 if deletion or unmerged.
. a space.
. sha1 for "src"; 0\{40\} if creation or unmerged.
. a space.
. sha1 for "dst"; 0\{40\} if creation, unmerged or "look at work tree".
. a space.
. status, followed by optional "score" number.
. a tab or a NUL when '-z' option is used.
. path for "src"
. a tab or a NUL when '-z' option is used; only exists for C or R.
. path for "dst"; only exists for C or R.
. an LF or a NUL when '-z' option is used, to terminate the record.

Possible status letters are:

- A: addition of a file
- C: copy of a file into a new one
- D: deletion of a file
- M: modification of the contents or mode of a file
- R: renaming of a file
- T: change in the type of the file
- U: file is unmerged (you must complete the merge before it can
be committed)
- X: "unknown" change type (most probably a bug, please report it)

Status letters C and R are always followed by a score (denoting the
percentage of similarity between the source and target of the move or
copy), and are the only ones to be so.

<sha1> is shown as all 0's if a file is new on the filesystem
and it is out of sync with the index.

Example:

------------------------------------------------
:100644 100644 5be4a4...... 000000...... M file.c
------------------------------------------------

When `-z` option is not used, TAB, LF, and backslash characters
in pathnames are represented as `\t`, `\n`, and `\\`,
respectively.

diff format for merges
----------------------

"git-diff-tree", "git-diff-files" and "git-diff --raw"
can take '-c' or '--cc' option
to generate diff output also for merge commits.  The output differs
from the format described above in the following way:

. there is a colon for each parent
. there are more "src" modes and "src" sha1
. status is concatenated status characters for each parent
. no optional "score" number
. single path, only for "dst"

Example:

------------------------------------------------
::100644 100644 100644 fabadb8... cc95eb0... 4866510... MM	describe.c
------------------------------------------------

Note that 'combined diff' lists only files which were modified from
all parents.


include::diff-generate-patch.txt[]


other diff formats
------------------

The `--summary` option describes newly added, deleted, renamed and
copied files.  The `--stat` option adds diffstat(1) graph to the
output.  These options can be combined with other options, such as
`-p`, and are meant for human consumption.

When showing a change that involves a rename or a copy, `--stat` output
formats the pathnames compactly by combining common prefix and suffix of
the pathnames.  For example, a change that moves `arch/i386/Makefile` to
`arch/x86/Makefile` while modifying 4 lines will be shown like this:

------------------------------------
arch/{i386 => x86}/Makefile    |   4 +--
------------------------------------

The `--numstat` option gives the diffstat(1) information but is designed
for easier machine consumption.  An entry in `--numstat` output looks
like this:

----------------------------------------
1	2	README
3	1	arch/{i386 => x86}/Makefile
----------------------------------------

That is, from left to right:

. the number of added lines;
. a tab;
. the number of deleted lines;
. a tab;
. pathname (possibly with rename/copy information);
. a newline.

When `-z` output option is in effect, the output is formatted this way:

----------------------------------------
1	2	README NUL
3	1	NUL arch/i386/Makefile NUL arch/x86/Makefile NUL
----------------------------------------

That is:

. the number of added lines;
. a tab;
. the number of deleted lines;
. a tab;
. a NUL (only exists if renamed/copied);
. pathname in preimage;
. a NUL (only exists if renamed/copied);
. pathname in postimage (only exists if renamed/copied);
. a NUL.

The extra `NUL` before the preimage path in renamed case is to allow
scripts that read the output to tell if the current record being read is
a single-path record or a rename/copy record without reading ahead.
After reading added and deleted lines, reading up to `NUL` would yield
the pathname, but if that is `NUL`, the record will show two paths.
back to top