diff --git a/Documentation/Makefile b/Documentation/Makefile index 3cfa360a9e..741f14cfad 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -52,10 +52,15 @@ install: man # 'include' dependencies $(patsubst %.txt,%.1,$(wildcard git-diff-*.txt)): \ diff-format.txt diff-options.txt -$(patsubst %,%.1,git-fetch git-pull git-push): pull-fetch-param.txt $(patsubst %.txt,%.html,$(wildcard git-diff-*.txt)): \ diff-format.txt diff-options.txt + +$(patsubst %,%.1,git-fetch git-pull git-push): pull-fetch-param.txt $(patsubst %,%.html,git-fetch git-pull git-push): pull-fetch-param.txt + +$(patsubst %,%.1,git-merge git-pull): merge-pull-opts.txt +$(patsubst %,%.html,git-merge git-pull): merge-pull-opts.txt + git.7: ../README clean: diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt index 32300297d6..4cae41267a 100644 --- a/Documentation/git-add.txt +++ b/Documentation/git-add.txt @@ -3,7 +3,7 @@ git-add(1) NAME ---- -git-add - Add files to the cache. +git-add - Add files to the index file. SYNOPSIS -------- @@ -11,13 +11,14 @@ SYNOPSIS DESCRIPTION ----------- -A simple wrapper for git-update-index to add files to the cache for people used -to do "cvs add". +A simple wrapper for git-update-index to add files to the index, +for people used to do "cvs add". + OPTIONS ------- ...:: - Files to add to the cache. + Files to add to the index. -n:: Don't actually add the file(s), just show if they exist. @@ -26,6 +27,40 @@ OPTIONS Be verbose. +DISCUSSION +---------- + +The list of given to the command is fed to `git-ls-files` +command to list files that are not registerd in the index and +are not ignored/excluded by `$GIT_DIR/info/exclude` file or +`.gitignore` file in each directory. This means two things: + +. You can put the name of a directory on the command line, and + the command will add all files in it and its subdirectories; + +. Giving the name of a file that is already in index does not + run `git-update-index` on that path. + + +EXAMPLES +-------- +git-add Documentation/\\*.txt:: + + Adds all `\*.txt` files that are not in the index under + `Documentation` directory and its subdirectories. ++ +Note that the asterisk `\*` is quoted from the shell in this +example; this lets the command to include the files from +subdirectories of `Documentation/` directory. + +git-add git-*.sh:: + + Adds all git-*.sh scripts that are not in the index. + Because this example lets shell expand the asterisk + (i.e. you are listing the files explicitly), it does not + add `subdir/git-foo.sh` to the index. + + Author ------ Written by Linus Torvalds diff --git a/Documentation/git-fetch.txt b/Documentation/git-fetch.txt index 71693650c4..73f8a99ffe 100644 --- a/Documentation/git-fetch.txt +++ b/Documentation/git-fetch.txt @@ -37,6 +37,11 @@ include::pull-fetch-param.txt[] update the index and working directory, so use it with care. +SEE ALSO +-------- +gitlink:git-pull[1] + + Author ------ Written by Linus Torvalds and diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt index f3ef4c1e04..7a3abec02e 100644 --- a/Documentation/git-format-patch.txt +++ b/Documentation/git-format-patch.txt @@ -59,6 +59,26 @@ OPTIONS standard output, instead of saving them into a file per patch and implies --mbox. + +EXAMPLES +-------- + +git-format-patch -k --stdout R1..R2 | git-am -3 -k:: + Extract commits between revisions R1 and R2, and apply + them on top of the current branch using `git-am` to + cherry-pick them. + +git-format-patch origin:: + Extract commits the current branch accumulated since it + pulled from origin the last time in a patch form for + e-mail submission. + + +See Also +-------- +gitlink:git-am[1], gitlink:git-send-email + + Author ------ Written by Junio C Hamano diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt index 8c9c4d87e3..3e058db996 100644 --- a/Documentation/git-merge.txt +++ b/Documentation/git-merge.txt @@ -8,7 +8,7 @@ git-merge - Grand Unified Merge Driver SYNOPSIS -------- -'git-merge' [-n] [-s ]... ... +'git-merge' [-n] [--no-commit] [-s ]... ... DESCRIPTION @@ -19,14 +19,7 @@ which drives multiple merge strategy scripts. OPTIONS ------- --n:: - Do not show diffstat at the end of the merge. - --s :: - use that merge strategy; can be given more than once to - specify them in the order they should be tried. If - there is no `-s` option, built-in list of strategies is - used instead. +include::merge-pull-opts.txt[] :: The commit message to be used for the merge commit (in case @@ -44,7 +37,7 @@ OPTIONS SEE ALSO -------- -gitlink:git-fmt-merge-msg[1] +gitlink:git-fmt-merge-msg[1], gitlink:git-pull[1] Author diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt index cef4c0ae38..ec10a2f409 100644 --- a/Documentation/git-pull.txt +++ b/Documentation/git-pull.txt @@ -8,18 +8,15 @@ git-pull - Pull and merge from another repository. SYNOPSIS -------- -'git-pull' ... +'git-pull' ... DESCRIPTION ----------- -Runs 'git-fetch' with the given parameters. +Runs `git-fetch` with the given parameters, and calls `git-merge` +to merge the retrieved head(s) into the current branch. -When only one ref is downloaded, runs 'git resolve' to merge it -into the local HEAD. Otherwise uses 'git octopus' to merge them -into the local HEAD. - -Note that you can use '.' (current directory) as the +Note that you can use `.` (current directory) as the to pull from the local repository -- this is useful when merging local branches into the current branch. @@ -29,8 +26,125 @@ include::pull-fetch-param.txt[] -a, \--append:: Append ref names and object names of fetched refs to the - existing contents of $GIT_DIR/FETCH_HEAD. Without this - option old data in $GIT_DIR/FETCH_HEAD will be overwritten. + existing contents of `$GIT_DIR/FETCH_HEAD`. Without this + option old data in `$GIT_DIR/FETCH_HEAD` will be overwritten. + +include::merge-pull-opts.txt[] + + +MERGE STRATEGIES +---------------- + +resolve:: + This can only resolve two heads (i.e. the current branch + and another branch you pulled from) using 3-way merge + algorithm. It tries to carefully detect criss-cross + merge ambiguities and is considered generally safe and + fast. This is the default merge strategy when pulling + one branch. + +recursive:: + This can only resolve two heads using 3-way merge + algorithm. When there are more than one common + ancestors that can be used for 3-way merge, it creates a + merged tree of the common ancestores and uses that as + the reference tree for the 3-way merge. This has been + reported to result in fewer merge conflicts without + causing mis-merges by tests done on actual merge commits + taken from Linux 2.6 kernel development history. + Additionally this can detect and handle merges involving + renames. + +octopus:: + This resolves more than two-head case, but refuses to do + complex merge that needs manual resolution. It is + primarily meant to be used for bundling topic branch + heads together. This is the default merge strategy when + pulling more than one branch. + +ours:: + This resolves any number of heads, but the result of the + merge is always the current branch head. It is meant to + be used to supersede old development history of side + branches. + + +EXAMPLES +-------- + +git pull, git pull origin:: + Fetch the default head from the repository you cloned + from and merge it into your current branch. + +git pull -s ours . obsolete:: + Merge local branch `obsolete` into the current branch, + using `ours` merge strategy. + +git pull . fixes enhancements:: + Bundle local branch `fixes` and `enhancements` on top of + the current branch, making an Octopus merge. + +git pull --no-commit . maint:: + Merge local branch `maint` into the current branch, but + do not make a commit automatically. This can be used + when you want to include further changes to the merge, + or want to write your own merge commit message. ++ +You should refrain from abusing this option to sneak substantial +changes into a merge commit. Small fixups like bumping +release/version name would be acceptable. + +Command line pull of multiple branches from one repository:: ++ +------------------------------------------------ +$ cat .git/remotes/origin +URL: git://git.kernel.org/pub/scm/git/git.git +Pull: master:origin + +$ git checkout master +$ git fetch origin master:origin +pu:pu maint:maint +$ git pull . origin +------------------------------------------------ ++ +Here, a typical `$GIT_DIR/remotes/origin` file from a +`git-clone` operation is used in combination with +command line options to `git-fetch` to first update +multiple branches of the local repository and then +to merge the remote `origin` branch into the local +`master` branch. The local `pu` branch is updated +even if it does not result in a fast forward update. +Here, the pull can obtain its objects from the local +repository using `.`, as the previous `git-fetch` is +known to have already obtained and made available +all the necessary objects. + + +Pull of multiple branches from one repository using `$GIT_DIR/remotes` file:: ++ +------------------------------------------------ +$ cat .git/remotes/origin +URL: git://git.kernel.org/pub/scm/git/git.git +Pull: master:origin +Pull: +pu:pu +Pull: maint:maint + +$ git checkout master +$ git pull origin +------------------------------------------------ ++ +Here, a typical `$GIT_DIR/remotes/origin` file from a +`git-clone` operation has been hand-modified to include +the branch-mapping of additional remote and local +heads directly. A single `git-pull` operation while +in the `master` branch will fetch multiple heads and +merge the remote `origin` head into the current, +local `master` branch. + + +SEE ALSO +-------- +gitlink:git-fetch[1], gitlink:git-merge[1] + Author ------ @@ -39,7 +153,9 @@ and Junio C Hamano Documentation -------------- -Documentation by David Greaves, Junio C Hamano and the git-list . +Documentation by Jon Loeliger, +David Greaves, +Junio C Hamano and the git-list . GIT --- diff --git a/Documentation/merge-pull-opts.txt b/Documentation/merge-pull-opts.txt new file mode 100644 index 0000000000..d9164a04a6 --- /dev/null +++ b/Documentation/merge-pull-opts.txt @@ -0,0 +1,14 @@ +-n, --no-summary:: + Do not show diffstat at the end of the merge. + +--no-commit:: + Perform the merge but pretend the merge failed and do + not autocommit, to give the user a chance to inspect and + further tweak the merge result before committing. + +-s :: + use that merge strategy; can be given more than once to + specify them in the order they should be tried. If + there is no `-s` option, built-in list of strategies is + used instead (`git-merge-resolve` when merging a single + head, `git-merge-octopus` otherwise). diff --git a/Documentation/pull-fetch-param.txt b/Documentation/pull-fetch-param.txt index e8db9d7ca5..57e9ddf0d6 100644 --- a/Documentation/pull-fetch-param.txt +++ b/Documentation/pull-fetch-param.txt @@ -1,7 +1,8 @@ :: - The "remote" repository to pull from. One of the - following notations can be used to name the repository - to pull from: + The "remote" repository that is the source of a fetch + or pull operation, or the destination of a push operation. + One of the following notations can be used + to name the remote repository: + =============================================================== - Rsync URL: rsync://remote.machine/path/to/repo.git/ @@ -12,66 +13,107 @@ =============================================================== + In addition to the above, as a short-hand, the name of a -file in $GIT_DIR/remotes directory can be given; the +file in `$GIT_DIR/remotes` directory can be given; the named file should be in the following format: + URL: one of the above URL format - Push: ... - Pull: ... + Push: + Pull: + When such a short-hand is specified in place of without parameters on the command -line, ... specified on Push lines or Pull lines -are used for "git push" and "git fetch/pull", -respectively. +line, specified on `Push:` lines or `Pull:` +lines are used for `git-push` and `git-fetch`/`git-pull`, +respectively. Multiple `Push:` and and `Pull:` lines may +be specified for additional branch mappings. + -The name of a file in $GIT_DIR/branches directory can be +The name of a file in `$GIT_DIR/branches` directory can be specified as an older notation short-hand; the named file should contain a single line, a URL in one of the -above formats, optionally followed by a hash '#' and the +above formats, optionally followed by a hash `#` and the name of remote head (URL fragment notation). -$GIT_DIR/branches/ file that stores a +`$GIT_DIR/branches/` file that stores a without the fragment is equivalent to have this in the -corresponding file in the $GIT_DIR/remotes/ directory +corresponding file in the `$GIT_DIR/remotes/` directory. + URL: Pull: refs/heads/master: + -while having # is equivalent to +while having `#` is equivalent to + URL: Pull: refs/heads/: :: The canonical format of a parameter is - '+?:'; that is, an optional plus '+', followed - by the source ref, followed by a colon ':', followed by + `+?:`; that is, an optional plus `+`, followed + by the source ref, followed by a colon `:`, followed by the destination ref. + -When used in "git push", the side can be an +When used in `git-push`, the side can be an arbitrary "SHA1 expression" that can be used as an -argument to "git-cat-file -t". E.g. "master~4" (push +argument to `git-cat-file -t`. E.g. `master~4` (push four parents before the current master head). + -For "git push", the local ref that matches is used +For `git-push`, the local ref that matches is used to fast forward the remote ref that matches . If -the optional plus '+' is used, the remote ref is updated +the optional plus `+` is used, the remote ref is updated even if it does not result in a fast forward update. + -For "git fetch/pull", the remote ref that matches +For `git-fetch` and `git-pull`, the remote ref that matches is fetched, and if is not empty string, the local ref that matches it is fast forwarded using . -Again, if the optional plus '+' is used, the local ref +Again, if the optional plus `+` is used, the local ref is updated even if it does not result in a fast forward update. + +[NOTE] +If the remote branch from which you want to pull is +modified in non-linear ways such as being rewound and +rebased frequently, then a pull will attempt a merge with +an older version of itself, likely conflict, and fail. +It is under these conditions that you would want to use +the `+` sign to indicate non-fast-forward updates will +be needed. There is currently no easy way to determine +or declare that a branch will be made available in a +repository with this behavior; the pulling user simply +must know this is the expected usage pattern for a branch. ++ +[NOTE] +You never do your own development on branches that appear +on the right hand side of a colon on `Pull:` lines; +they are to be updated by `git-fetch`. The corollary is that +a local branch should be introduced and named on a +right-hand-side if you intend to do development derived from +that branch. +This leads to the common `Pull: master:origin` mapping of a +remote `master` branch to a local `origin` branch, which +is then merged to a local development branch, again typically +named `master`. ++ +[NOTE] +There is a difference between listing multiple +directly on `git-pull` command line and having multiple +`Pull:` lines for a and running +`git-pull` command without any explicit parameters. + listed explicitly on the command line are always +merged into the current branch after fetching. In other words, +if you list more than one remote refs, you would be making +an Octopus. While `git-pull` run without any explicit +parameter takes default s from `Pull:` lines, it +merges only the first found into the current branch, +after fetching all the remote refs. This is because making an +Octopus from remote refs is rarely done, while keeping track +of multiple remote heads in one-go by fetching more than one +is often useful. ++ Some short-cut notations are also supported. + -* For backward compatibility, "tag" is almost ignored; +* For backward compatibility, `tag` is almost ignored; it just makes the following parameter to mean a - refspec "refs/tags/:refs/tags/". + refspec `refs/tags/:refs/tags/`. * A parameter without a colon is equivalent to - : when pulling/fetching, and : when + : when pulling/fetching, and `:` when pushing. That is, do not store it locally if fetching, and update the same name if pushing. diff --git a/Makefile b/Makefile index f96da67822..2ae69e3aa1 100644 --- a/Makefile +++ b/Makefile @@ -52,7 +52,7 @@ # DEFINES += -DUSE_STDEV -GIT_VERSION = 0.99.9c +GIT_VERSION = 0.99.9d CFLAGS = -g -O2 -Wall ALL_CFLAGS = $(CFLAGS) $(PLATFORM_DEFINES) $(DEFINES) diff --git a/copy.c b/copy.c index 20092757d3..e1cd5d0650 100644 --- a/copy.c +++ b/copy.c @@ -10,10 +10,13 @@ int copy_fd(int ifd, int ofd) if (!len) break; if (len < 0) { + int read_error; if (errno == EAGAIN) continue; + read_error = errno; + close(ifd); return error("copy-fd: read returned %s", - strerror(errno)); + strerror(read_error)); } while (1) { int written = write(ofd, buf, len); diff --git a/debian/changelog b/debian/changelog index cc97660185..c643015a7d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +git-core (0.99.9d-0) unstable; urgency=low + + * GIT 0.99.9d + + -- Junio C Hamano Sat, 5 Nov 2005 11:46:37 -0800 + git-core (0.99.9c-0) unstable; urgency=low * GIT 0.99.9c diff --git a/git-clone.sh b/git-clone.sh index c27a913b1d..1adf604172 100755 --- a/git-clone.sh +++ b/git-clone.sh @@ -126,8 +126,7 @@ yes,yes) fi && rm -f "$D/.git/objects/sample" && cd "$repo" && - find objects -type f -print | - cpio -puamd$l "$D/.git/" || exit 1 + find objects -depth -print | cpio -puamd$l "$D/.git/" || exit 1 ;; yes) mkdir -p "$D/.git/objects/info" diff --git a/git-format-patch.sh b/git-format-patch.sh index 0207ab18a3..5b93ff80a0 100755 --- a/git-format-patch.sh +++ b/git-format-patch.sh @@ -92,11 +92,18 @@ filelist=$tmp-files # 3. "rev1" "rev2 is equivalent to "rev1..rev2" # # We want to take a sequence of "rev1..rev2" in general. +# Also, "rev1.." should mean "rev1..HEAD"; git-diff users are +# familiar with that syntax. case "$#,$1" in 1,?*..?*) # single "rev1..rev2" ;; +1,?*..) + # single "rev1.." should mean "rev1..HEAD" + set x "$1"HEAD" + shift + ;; 1,*) # single rev1 set x "$1..HEAD" diff --git a/git-pull.sh b/git-pull.sh index 96016270b4..e23d4f5597 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -7,7 +7,7 @@ . git-sh-setup || die "Not a git archive" usage () { - die "git pull [-n] [-s strategy]... ..." + die "git pull [-n] [--no-commit] [-s strategy]... ..." } strategy_args= no_summary= no_commit= diff --git a/git-tag.sh b/git-tag.sh index faa766799d..bd92753674 100755 --- a/git-tag.sh +++ b/git-tag.sh @@ -61,33 +61,35 @@ type=$(git-cat-file -t $object) || exit 1 tagger=$(git-var GIT_COMMITTER_IDENT) || exit 1 : ${username:=$(expr "$tagger" : '\(.*>\)')} -trap 'rm -f .tmp-tag* .tagmsg .editmsg' 0 +trap 'rm -f "$GIT_DIR"/TAG_TMP* "$GIT_DIR"/TAG_FINALMSG "$GIT_DIR"/TAG_EDITMSG' 0 if [ "$annotate" ]; then if [ -z "$message" ]; then ( echo "#" echo "# Write a tag message" - echo "#" ) > .editmsg - ${VISUAL:-${EDITOR:-vi}} .editmsg || exit + echo "#" ) > "$GIT_DIR"/TAG_EDITMSG + ${VISUAL:-${EDITOR:-vi}} "$GIT_DIR"/TAG_EDITMSG || exit else - echo "$message" > .editmsg + echo "$message" >"$GIT_DIR"/TAG_EDITMSG fi - grep -v '^#' < .editmsg | git-stripspace > .tagmsg + grep -v '^#' <"$GIT_DIR"/TAG_EDITMSG | + git-stripspace >"$GIT_DIR"/TAG_FINALMSG - [ -s .tagmsg ] || { + [ -s "$GIT_DIR"/TAG_FINALMSG ] || { echo >&2 "No tag message?" exit 1 } - ( echo -e "object $object\ntype $type\ntag $name\ntagger $tagger\n"; cat .tagmsg ) > .tmp-tag - rm -f .tmp-tag.asc .tagmsg + ( echo -e "object $object\ntype $type\ntag $name\ntagger $tagger\n"; + cat "$GIT_DIR"/TAG_FINALMSG ) >"$GIT_DIR"/TAG_TMP + rm -f "$GIT_DIR"/TAG_TMP.asc "$GIT_DIR"/TAG_FINALMSG if [ "$signed" ]; then - gpg -bsa -u "$username" .tmp-tag && - cat .tmp-tag.asc >>.tmp-tag || + gpg -bsa -u "$username" "$GIT_DIR"/TAG_TMP && + cat "$GIT_DIR"/TAG_TMP.asc >>"$GIT_DIR"/TAG_TMP || die "failed to sign the tag with GPG." fi - object=$(git-mktag < .tmp-tag) + object=$(git-mktag < "$GIT_DIR"/TAG_TMP) fi mkdir -p "$GIT_DIR/refs/tags" diff --git a/http-fetch.c b/http-fetch.c index a1b03cd9c8..b12779dcb4 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -520,12 +520,17 @@ static void start_request(struct transfer_request *request) static void finish_request(struct transfer_request *request) { + struct stat st; + fchmod(request->local, 0444); close(request->local); if (request->http_code == 416) { fprintf(stderr, "Warning: requested range invalid; we may already have all the data.\n"); } else if (request->curl_result != CURLE_OK) { + if (stat(request->tmpfile, &st) == 0) + if (st.st_size == 0) + unlink(request->tmpfile); return; } diff --git a/init-db.c b/init-db.c index ca6fa4d420..bd88291b0e 100644 --- a/init-db.c +++ b/init-db.c @@ -21,7 +21,7 @@ static void safe_create_dir(const char *dir) static int copy_file(const char *dst, const char *src, int mode) { - int fdi, fdo; + int fdi, fdo, status; mode = (mode & 0111) ? 0777 : 0666; if ((fdi = open(src, O_RDONLY)) < 0) @@ -30,30 +30,9 @@ static int copy_file(const char *dst, const char *src, int mode) close(fdi); return fdo; } - while (1) { - char buf[BUFSIZ]; - ssize_t leni, leno, ofs; - leni = read(fdi, buf, sizeof(buf)); - if (leni < 0) { - error_return: - close(fdo); - close(fdi); - return -1; - } - if (!leni) - break; - ofs = 0; - do { - leno = write(fdo, buf+ofs, leni); - if (leno < 0) - goto error_return; - leni -= leno; - ofs += leno; - } while (0 < leni); - } + status = copy_fd(fdi, fdo); close(fdo); - close(fdi); - return 0; + return status; } static void copy_templates_1(char *path, int baselen,