Merge branch 'ap/clone-origin' of .git/ into next

* 'ap/clone-origin' of .git/:
  Use .git/config for storing "origin" shortcut repository
  sha1_object_info(): be consistent with read_sha1_file()
  shortlog: use pager
  cvsimport: style fixup.
  git-svn: use ~/.subversion config files when using SVN:: libraries
  Teach bash about git-am/git-apply and their whitespace options.
  Cache the list of merge strategies and available commands during load.
  Support --strategy=x completion in addition to --strategy x.
  Teach bash about git-repo-config.
  Support bash completion of refs/remote.
  Teach bash about git log/show/whatchanged options.
  Teach bash how to complete git-rebase.
  Teach bash how to complete git-cherry-pick.
  Teach bash how to complete git-format-patch.
  Add current branch in PS1 support to git-completion.bash.
  Teach bash how to complete options for git-name-rev.
  Hide plumbing/transport commands from bash completion.
  Teach git-completion.bash how to complete git-merge.
  Update documentation to remove incorrect GIT_DIFF_OPTS example.
This commit is contained in:
Junio C Hamano
2006-11-27 17:14:31 -08:00
8 changed files with 621 additions and 191 deletions

View File

@@ -65,62 +65,17 @@ Generating patches with -p
When "git-diff-index", "git-diff-tree", or "git-diff-files" are run
with a '-p' option, they do not produce the output described above;
instead they produce a patch file.
instead they produce a patch file. You can customize the creation
of such patches via the GIT_EXTERNAL_DIFF and the GIT_DIFF_OPTS
environment variables.
The patch generation can be customized at two levels.
1. When the environment variable 'GIT_EXTERNAL_DIFF' is not set,
these commands internally invoke "diff" like this:
diff -L a/<path> -L b/<path> -pu <old> <new>
+
For added files, `/dev/null` is used for <old>. For removed
files, `/dev/null` is used for <new>
+
The "diff" formatting options can be customized via the
environment variable 'GIT_DIFF_OPTS'. For example, if you
prefer context diff:
GIT_DIFF_OPTS=-c git-diff-index -p HEAD
2. When the environment variable 'GIT_EXTERNAL_DIFF' is set, the
program named by it is called, instead of the diff invocation
described above.
+
For a path that is added, removed, or modified,
'GIT_EXTERNAL_DIFF' is called with 7 parameters:
path old-file old-hex old-mode new-file new-hex new-mode
+
where:
<old|new>-file:: are files GIT_EXTERNAL_DIFF can use to read the
contents of <old|new>,
<old|new>-hex:: are the 40-hexdigit SHA1 hashes,
<old|new>-mode:: are the octal representation of the file modes.
+
The file parameters can point at the user's working file
(e.g. `new-file` in "git-diff-files"), `/dev/null` (e.g. `old-file`
when a new file is added), or a temporary file (e.g. `old-file` in the
index). 'GIT_EXTERNAL_DIFF' should not worry about unlinking the
temporary file --- it is removed when 'GIT_EXTERNAL_DIFF' exits.
For a path that is unmerged, 'GIT_EXTERNAL_DIFF' is called with 1
parameter, <path>.
git specific extension to diff format
-------------------------------------
What -p option produces is slightly different from the
traditional diff format.
What the -p option produces is slightly different from the traditional
diff format.
1. It is preceded with a "git diff" header, that looks like
this:
diff --git a/file1 b/file2
diff --git a/file1 b/file2
+
The `a/` and `b/` filenames are the same unless rename/copy is
involved. Especially, even for a creation or a deletion,

View File

@@ -639,11 +639,35 @@ git Commits
git Diffs
~~~~~~~~~
'GIT_DIFF_OPTS'::
Only valid setting is "--unified=??" or "-u??" to set the
number of context lines shown when a unified diff is created.
This takes precedence over any "-U" or "--unified" option
value passed on the git diff command line.
'GIT_EXTERNAL_DIFF'::
see the "generating patches" section in :
gitlink:git-diff-index[1];
gitlink:git-diff-files[1];
gitlink:git-diff-tree[1]
When the environment variable 'GIT_EXTERNAL_DIFF' is set, the
program named by it is called, instead of the diff invocation
described above. For a path that is added, removed, or modified,
'GIT_EXTERNAL_DIFF' is called with 7 parameters:
path old-file old-hex old-mode new-file new-hex new-mode
+
where:
<old|new>-file:: are files GIT_EXTERNAL_DIFF can use to read the
contents of <old|new>,
<old|new>-hex:: are the 40-hexdigit SHA1 hashes,
<old|new>-mode:: are the octal representation of the file modes.
+
The file parameters can point at the user's working file
(e.g. `new-file` in "git-diff-files"), `/dev/null` (e.g. `old-file`
when a new file is added), or a temporary file (e.g. `old-file` in the
index). 'GIT_EXTERNAL_DIFF' should not worry about unlinking the
temporary file --- it is removed when 'GIT_EXTERNAL_DIFF' exits.
+
For a path that is unmerged, 'GIT_EXTERNAL_DIFF' is called with 1
parameter, <path>.
other
~~~~~

View File

@@ -18,26 +18,82 @@
# 2) Added the following line to your .bashrc:
# source ~/.git-completion.sh
#
# 3) You may want to make sure the git executable is available
# in your PATH before this script is sourced, as some caching
# is performed while the script loads. If git isn't found
# at source time then all lookups will be done on demand,
# which may be slightly slower.
#
# 4) Consider changing your PS1 to also show the current branch:
# PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
#
# The argument to __git_ps1 will be displayed only if you
# are currently in a git repository. The %s token will be
# the name of the current branch.
#
__gitdir ()
{
echo "${__git_dir:-$(git rev-parse --git-dir 2>/dev/null)}"
}
__git_ps1 ()
{
local b="$(git symbolic-ref HEAD 2>/dev/null)"
if [ -n "$b" ]; then
if [ -n "$1" ]; then
printf "$1" "${b##refs/heads/}"
else
printf " (%s)" "${b##refs/heads/}"
fi
fi
}
__git_heads ()
{
local cmd i is_hash=y dir="${1:-$(__gitdir)}"
if [ -d "$dir" ]; then
for i in $(git --git-dir="$dir" \
for-each-ref --format='%(refname)' \
refs/heads ); do
echo "${i#refs/heads/}"
done
return
fi
for i in $(git-ls-remote "$dir" 2>/dev/null); do
case "$is_hash,$i" in
y,*) is_hash=n ;;
n,*^{}) is_hash=y ;;
n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
n,*) is_hash=y; echo "$i" ;;
esac
done
}
__git_refs ()
{
local cmd i is_hash=y dir="${1:-$(__gitdir)}"
if [ -d "$dir" ]; then
cmd=git-peek-remote
else
cmd=git-ls-remote
if [ -e "$dir/HEAD" ]; then echo HEAD; fi
for i in $(git --git-dir="$dir" \
for-each-ref --format='%(refname)' \
refs/tags refs/heads refs/remotes); do
case "$i" in
refs/tags/*) echo "${i#refs/tags/}" ;;
refs/heads/*) echo "${i#refs/heads/}" ;;
refs/remotes/*) echo "${i#refs/remotes/}" ;;
*) echo "$i" ;;
esac
done
return
fi
for i in $($cmd "$dir" 2>/dev/null); do
for i in $(git-ls-remote "$dir" 2>/dev/null); do
case "$is_hash,$i" in
y,*) is_hash=n ;;
n,*^{}) is_hash=y ;;
n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;;
n,*) is_hash=y; echo "$i" ;;
esac
done
@@ -62,6 +118,23 @@ __git_refs2 ()
done
}
__git_refs_remotes ()
{
local cmd i is_hash=y
for i in $(git-ls-remote "$1" 2>/dev/null); do
case "$is_hash,$i" in
n,refs/heads/*)
is_hash=y
echo "$i:refs/remotes/$1/${i#refs/heads/}"
;;
y,*) is_hash=n ;;
n,*^{}) is_hash=y ;;
n,refs/tags/*) is_hash=y;;
n,*) is_hash=y; ;;
esac
done
}
__git_remotes ()
{
local i ngoff IFS=$'\n' d="$(__gitdir)"
@@ -81,6 +154,22 @@ __git_remotes ()
done
}
__git_merge_strategies ()
{
if [ -n "$__git_merge_strategylist" ]; then
echo "$__git_merge_strategylist"
return
fi
sed -n "/^all_strategies='/{
s/^all_strategies='//
s/'//
p
q
}" "$(git --exec-path)/git-merge"
}
__git_merge_strategylist=
__git_merge_strategylist="$(__git_merge_strategies 2>/dev/null)"
__git_complete_file ()
{
local pfx ls ref cur="${COMP_WORDS[COMP_CWORD]}"
@@ -115,6 +204,84 @@ __git_complete_file ()
esac
}
__git_complete_revlist ()
{
local pfx cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
*...*)
pfx="${cur%...*}..."
cur="${cur#*...}"
COMPREPLY=($(compgen -P "$pfx" -W "$(__git_refs)" -- "$cur"))
;;
*..*)
pfx="${cur%..*}.."
cur="${cur#*..}"
COMPREPLY=($(compgen -P "$pfx" -W "$(__git_refs)" -- "$cur"))
;;
*)
COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
;;
esac
}
__git_commands ()
{
if [ -n "$__git_commandlist" ]; then
echo "$__git_commandlist"
return
fi
local i IFS=" "$'\n'
for i in $(git help -a|egrep '^ ')
do
case $i in
check-ref-format) : plumbing;;
commit-tree) : plumbing;;
convert-objects) : plumbing;;
cvsserver) : daemon;;
daemon) : daemon;;
fetch-pack) : plumbing;;
hash-object) : plumbing;;
http-*) : transport;;
index-pack) : plumbing;;
local-fetch) : plumbing;;
mailinfo) : plumbing;;
mailsplit) : plumbing;;
merge-*) : plumbing;;
mktree) : plumbing;;
mktag) : plumbing;;
pack-objects) : plumbing;;
pack-redundant) : plumbing;;
pack-refs) : plumbing;;
parse-remote) : plumbing;;
patch-id) : plumbing;;
peek-remote) : plumbing;;
read-tree) : plumbing;;
receive-pack) : plumbing;;
rerere) : plumbing;;
rev-list) : plumbing;;
rev-parse) : plumbing;;
runstatus) : plumbing;;
sh-setup) : internal;;
shell) : daemon;;
send-pack) : plumbing;;
show-index) : plumbing;;
ssh-*) : transport;;
stripspace) : plumbing;;
symbolic-ref) : plumbing;;
unpack-file) : plumbing;;
unpack-objects) : plumbing;;
update-ref) : plumbing;;
update-server-info) : daemon;;
upload-archive) : plumbing;;
upload-pack) : plumbing;;
write-tree) : plumbing;;
*) echo $i;;
esac
done
}
__git_commandlist=
__git_commandlist="$(__git_commands 2>/dev/null)"
__git_aliases ()
{
local i IFS=$'\n'
@@ -140,6 +307,54 @@ __git_aliased_command ()
done
}
__git_whitespacelist="nowarn warn error error-all strip"
_git_am ()
{
local cur="${COMP_WORDS[COMP_CWORD]}"
if [ -d .dotest ]; then
COMPREPLY=($(compgen -W "
--skip --resolved
" -- "$cur"))
return
fi
case "$cur" in
--whitespace=*)
COMPREPLY=($(compgen -W "$__git_whitespacelist" \
-- "${cur##--whitespace=}"))
return
;;
--*)
COMPREPLY=($(compgen -W "
--signoff --utf8 --binary --3way --interactive
--whitespace=
" -- "$cur"))
return
esac
COMPREPLY=()
}
_git_apply ()
{
local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
--whitespace=*)
COMPREPLY=($(compgen -W "$__git_whitespacelist" \
-- "${cur##--whitespace=}"))
return
;;
--*)
COMPREPLY=($(compgen -W "
--stat --numstat --summary --check --index
--cached --index-info --reverse --reject --unidiff-zero
--apply --no-add --exclude=
--whitespace= --inaccurate-eof --verbose
" -- "$cur"))
return
esac
COMPREPLY=()
}
_git_branch ()
{
local cur="${COMP_WORDS[COMP_CWORD]}"
@@ -168,6 +383,21 @@ _git_checkout ()
COMPREPLY=($(compgen -W "-l -b $(__git_refs)" -- "$cur"))
}
_git_cherry_pick ()
{
local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
--*)
COMPREPLY=($(compgen -W "
--edit --no-commit
" -- "$cur"))
;;
*)
COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
;;
esac
}
_git_diff ()
{
__git_complete_file
@@ -209,6 +439,26 @@ _git_fetch ()
esac
}
_git_format_patch ()
{
local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
--*)
COMPREPLY=($(compgen -W "
--stdout --attach --thread
--output-directory
--numbered --start-number
--keep-subject
--signoff
--in-reply-to=
--full-index --binary
" -- "$cur"))
return
;;
esac
__git_complete_revlist
}
_git_ls_remote ()
{
local cur="${COMP_WORDS[COMP_CWORD]}"
@@ -222,22 +472,53 @@ _git_ls_tree ()
_git_log ()
{
local pfx cur="${COMP_WORDS[COMP_CWORD]}"
local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
*...*)
pfx="${cur%...*}..."
cur="${cur#*...}"
COMPREPLY=($(compgen -P "$pfx" -W "$(__git_refs)" -- "$cur"))
--pretty=*)
COMPREPLY=($(compgen -W "
oneline short medium full fuller email raw
" -- "${cur##--pretty=}"))
return
;;
*..*)
pfx="${cur%..*}.."
cur="${cur#*..}"
COMPREPLY=($(compgen -P "$pfx" -W "$(__git_refs)" -- "$cur"))
;;
*)
COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
--*)
COMPREPLY=($(compgen -W "
--max-count= --max-age= --since= --after=
--min-age= --before= --until=
--root --not --topo-order --date-order
--no-merges
--abbrev-commit --abbrev=
--relative-date
--author= --committer= --grep=
--all-match
--pretty= --name-status --name-only
" -- "$cur"))
return
;;
esac
__git_complete_revlist
}
_git_merge ()
{
local cur="${COMP_WORDS[COMP_CWORD]}"
case "${COMP_WORDS[COMP_CWORD-1]}" in
-s|--strategy)
COMPREPLY=($(compgen -W "$(__git_merge_strategies)" -- "$cur"))
return
esac
case "$cur" in
--strategy=*)
COMPREPLY=($(compgen -W "$(__git_merge_strategies)" \
-- "${cur##--strategy=}"))
return
;;
--*)
COMPREPLY=($(compgen -W "
--no-commit --no-summary --squash --strategy
" -- "$cur"))
return
esac
COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
}
_git_merge_base ()
@@ -246,6 +527,12 @@ _git_merge_base ()
COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
}
_git_name_rev ()
{
local cur="${COMP_WORDS[COMP_CWORD]}"
COMPREPLY=($(compgen -W "--tags --all --stdin" -- "$cur"))
}
_git_pull ()
{
local cur="${COMP_WORDS[COMP_CWORD]}"
@@ -298,6 +585,148 @@ _git_push ()
esac
}
_git_rebase ()
{
local cur="${COMP_WORDS[COMP_CWORD]}"
if [ -d .dotest ]; then
COMPREPLY=($(compgen -W "
--continue --skip --abort
" -- "$cur"))
return
fi
case "${COMP_WORDS[COMP_CWORD-1]}" in
-s|--strategy)
COMPREPLY=($(compgen -W "$(__git_merge_strategies)" -- "$cur"))
return
esac
case "$cur" in
--strategy=*)
COMPREPLY=($(compgen -W "$(__git_merge_strategies)" \
-- "${cur##--strategy=}"))
return
;;
--*)
COMPREPLY=($(compgen -W "
--onto --merge --strategy
" -- "$cur"))
return
esac
COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
}
_git_repo_config ()
{
local cur="${COMP_WORDS[COMP_CWORD]}"
local prv="${COMP_WORDS[COMP_CWORD-1]}"
case "$prv" in
branch.*.remote)
COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur"))
return
;;
branch.*.merge)
COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
return
;;
remote.*.fetch)
local remote="${prv#remote.}"
remote="${remote%.fetch}"
COMPREPLY=($(compgen -W "$(__git_refs_remotes "$remote")" \
-- "$cur"))
return
;;
remote.*.push)
local remote="${prv#remote.}"
remote="${remote%.push}"
COMPREPLY=($(compgen -W "$(git --git-dir="$(__gitdir)" \
for-each-ref --format='%(refname):%(refname)' \
refs/heads)" -- "$cur"))
return
;;
*.*)
COMPREPLY=()
return
;;
esac
case "$cur" in
--*)
COMPREPLY=($(compgen -W "
--global --list --replace-all
--get --get-all --get-regexp
--unset --unset-all
" -- "$cur"))
return
;;
branch.*.*)
local pfx="${cur%.*}."
cur="${cur##*.}"
COMPREPLY=($(compgen -P "$pfx" -W "remote merge" -- "$cur"))
return
;;
branch.*)
local pfx="${cur%.*}."
cur="${cur#*.}"
COMPREPLY=($(compgen -P "$pfx" -S . \
-W "$(__git_heads)" -- "$cur"))
return
;;
remote.*.*)
local pfx="${cur%.*}."
cur="${cur##*.}"
COMPREPLY=($(compgen -P "$pfx" -W "url fetch push" -- "$cur"))
return
;;
remote.*)
local pfx="${cur%.*}."
cur="${cur#*.}"
COMPREPLY=($(compgen -P "$pfx" -S . \
-W "$(__git_remotes)" -- "$cur"))
return
;;
esac
COMPREPLY=($(compgen -W "
apply.whitespace
core.fileMode
core.gitProxy
core.ignoreStat
core.preferSymlinkRefs
core.logAllRefUpdates
core.repositoryFormatVersion
core.sharedRepository
core.warnAmbiguousRefs
core.compression
core.legacyHeaders
i18n.commitEncoding
diff.color
diff.renameLimit
diff.renames
pager.color
status.color
log.showroot
show.difftree
showbranch.default
whatchanged.difftree
http.sslVerify
http.sslCert
http.sslKey
http.sslCAInfo
http.sslCAPath
http.maxRequests
http.lowSpeedLimit http.lowSpeedTime
http.noEPSV
pack.window
repack.useDeltaBaseOffset
pull.octopus pull.twohead
merge.summary
receive.unpackLimit
receive.denyNonFastForwards
user.name user.email
tar.umask
gitcvs.enabled
gitcvs.logfile
branch. remote.
" -- "$cur"))
}
_git_reset ()
{
local cur="${COMP_WORDS[COMP_CWORD]}"
@@ -305,12 +734,6 @@ _git_reset ()
COMPREPLY=($(compgen -W "$opt $(__git_refs)" -- "$cur"))
}
_git_show ()
{
local cur="${COMP_WORDS[COMP_CWORD]}"
COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
}
_git ()
{
local i c=1 command __git_dir
@@ -327,11 +750,11 @@ _git ()
done
if [ $c -eq $COMP_CWORD -a -z "$command" ]; then
COMPREPLY=($(compgen \
-W "--git-dir= --version \
$(git help -a|egrep '^ ') \
$(__git_aliases)" \
-- "${COMP_WORDS[COMP_CWORD]}"))
COMPREPLY=($(compgen -W "
--git-dir= --version --exec-path
$(__git_commands)
$(__git_aliases)
" -- "${COMP_WORDS[COMP_CWORD]}"))
return;
fi
@@ -339,20 +762,28 @@ _git ()
[ "$expansion" ] && command="$expansion"
case "$command" in
am) _git_am ;;
apply) _git_apply ;;
branch) _git_branch ;;
cat-file) _git_cat_file ;;
checkout) _git_checkout ;;
cherry-pick) _git_cherry_pick ;;
diff) _git_diff ;;
diff-tree) _git_diff_tree ;;
fetch) _git_fetch ;;
format-patch) _git_format_patch ;;
log) _git_log ;;
ls-remote) _git_ls_remote ;;
ls-tree) _git_ls_tree ;;
merge) _git_merge;;
merge-base) _git_merge_base ;;
name-rev) _git_name_rev ;;
pull) _git_pull ;;
push) _git_push ;;
rebase) _git_rebase ;;
repo-config) _git_repo_config ;;
reset) _git_reset ;;
show) _git_show ;;
show) _git_log ;;
show-branch) _git_log ;;
whatchanged) _git_log ;;
*) COMPREPLY=() ;;
@@ -367,20 +798,28 @@ _gitk ()
complete -o default -o nospace -F _git git
complete -o default -F _gitk gitk
complete -o default -F _git_am git-am
complete -o default -F _git_apply git-apply
complete -o default -F _git_branch git-branch
complete -o default -o nospace -F _git_cat_file git-cat-file
complete -o default -F _git_checkout git-checkout
complete -o default -F _git_cherry_pick git-cherry-pick
complete -o default -o nospace -F _git_diff git-diff
complete -o default -F _git_diff_tree git-diff-tree
complete -o default -o nospace -F _git_fetch git-fetch
complete -o default -o nospace -F _git_format_patch git-format-patch
complete -o default -o nospace -F _git_log git-log
complete -o default -F _git_ls_remote git-ls-remote
complete -o default -o nospace -F _git_ls_tree git-ls-tree
complete -o default -F _git_merge git-merge
complete -o default -F _git_merge_base git-merge-base
complete -o default -F _git_name_rev git-name-rev
complete -o default -o nospace -F _git_pull git-pull
complete -o default -o nospace -F _git_push git-push
complete -o default -F _git_rebase git-rebase
complete -o default -F _git_repo_config git-repo-config
complete -o default -F _git_reset git-reset
complete -o default -F _git_show git-show
complete -o default -F _git_log git-show
complete -o default -o nospace -F _git_log git-show-branch
complete -o default -o nospace -F _git_log git-whatchanged
@@ -389,15 +828,20 @@ complete -o default -o nospace -F _git_log git-whatchanged
# included the '.exe' suffix.
#
if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
complete -o default -F _git_apply git-apply.exe
complete -o default -o nospace -F _git git.exe
complete -o default -F _git_branch git-branch.exe
complete -o default -o nospace -F _git_cat_file git-cat-file.exe
complete -o default -o nospace -F _git_diff git-diff.exe
complete -o default -o nospace -F _git_diff_tree git-diff-tree.exe
complete -o default -o nospace -F _git_format_patch git-format-patch.exe
complete -o default -o nospace -F _git_log git-log.exe
complete -o default -o nospace -F _git_ls_tree git-ls-tree.exe
complete -o default -F _git_merge_base git-merge-base.exe
complete -o default -F _git_name_rev git-name-rev.exe
complete -o default -o nospace -F _git_push git-push.exe
complete -o default -F _git_repo_config git-repo-config
complete -o default -o nospace -F _git_log git-show.exe
complete -o default -o nospace -F _git_log git-show-branch.exe
complete -o default -o nospace -F _git_log git-whatchanged.exe
fi

View File

@@ -390,9 +390,9 @@ then
*) origin_track="$remote_top/$origin"
git-update-ref "refs/heads/$origin" "$head_sha1" ;;
esac &&
echo >"$GIT_DIR/remotes/$origin" \
"URL: $repo
Pull: refs/heads/$head_points_at:$origin_track" &&
git-repo-config remote."$origin".url "$repo" &&
git-repo-config remote."$origin".fetch \
"refs/heads/$head_points_at:$origin_track" &&
(cd "$GIT_DIR/$remote_top" && find . -type f -print) |
while read dotslref
do
@@ -406,8 +406,8 @@ Pull: refs/heads/$head_points_at:$origin_track" &&
then
continue
fi
echo "Pull: refs/heads/${name}:$remote_top/${name}"
done >>"$GIT_DIR/remotes/$origin" &&
git-repo-config remote."$origin".fetch "refs/heads/${name}:$remote_top/${name}" '^$'
done &&
case "$use_separate_remote" in
t)
rm -f "refs/remotes/$origin/HEAD"

View File

@@ -29,7 +29,7 @@ use IPC::Open2;
$SIG{'PIPE'}="IGNORE";
$ENV{'TZ'}="UTC";
our($opt_h,$opt_o,$opt_v,$opt_k,$opt_u,$opt_d,$opt_p,$opt_C,$opt_z,$opt_i,$opt_P, $opt_s,$opt_m,$opt_M,$opt_A,$opt_S,$opt_L);
our ($opt_h,$opt_o,$opt_v,$opt_k,$opt_u,$opt_d,$opt_p,$opt_C,$opt_z,$opt_i,$opt_P, $opt_s,$opt_m,$opt_M,$opt_A,$opt_S,$opt_L);
my (%conv_author_name, %conv_author_email);
sub usage() {
@@ -90,15 +90,15 @@ usage if $opt_h;
@ARGV <= 1 or usage();
if($opt_d) {
if ($opt_d) {
$ENV{"CVSROOT"} = $opt_d;
} elsif(-f 'CVS/Root') {
} elsif (-f 'CVS/Root') {
open my $f, '<', 'CVS/Root' or die 'Failed to open CVS/Root';
$opt_d = <$f>;
chomp $opt_d;
close $f;
$ENV{"CVSROOT"} = $opt_d;
} elsif($ENV{"CVSROOT"}) {
} elsif ($ENV{"CVSROOT"}) {
$opt_d = $ENV{"CVSROOT"};
} else {
die "CVSROOT needs to be set";
@@ -141,7 +141,7 @@ use File::Temp qw(tempfile);
use POSIX qw(strftime dup2);
sub new {
my($what,$repo,$subdir) = @_;
my ($what,$repo,$subdir) = @_;
$what=ref($what) if ref($what);
my $self = {};
@@ -161,38 +161,38 @@ sub new {
sub conn {
my $self = shift;
my $repo = $self->{'fullrep'};
if($repo =~ s/^:pserver(?:([^:]*)):(?:(.*?)(?::(.*?))?@)?([^:\/]*)(?::(\d*))?//) {
my($param,$user,$pass,$serv,$port) = ($1,$2,$3,$4,$5);
if ($repo =~ s/^:pserver(?:([^:]*)):(?:(.*?)(?::(.*?))?@)?([^:\/]*)(?::(\d*))?//) {
my ($param,$user,$pass,$serv,$port) = ($1,$2,$3,$4,$5);
my($proxyhost,$proxyport);
if($param && ($param =~ m/proxy=([^;]+)/)) {
my ($proxyhost,$proxyport);
if ($param && ($param =~ m/proxy=([^;]+)/)) {
$proxyhost = $1;
# Default proxyport, if not specified, is 8080.
$proxyport = 8080;
if($ENV{"CVS_PROXY_PORT"}) {
if ($ENV{"CVS_PROXY_PORT"}) {
$proxyport = $ENV{"CVS_PROXY_PORT"};
}
if($param =~ m/proxyport=([^;]+)/){
if ($param =~ m/proxyport=([^;]+)/) {
$proxyport = $1;
}
}
$user="anonymous" unless defined $user;
my $rr2 = "-";
unless($port) {
unless ($port) {
$rr2 = ":pserver:$user\@$serv:$repo";
$port=2401;
}
my $rr = ":pserver:$user\@$serv:$port$repo";
unless($pass) {
unless ($pass) {
open(H,$ENV{'HOME'}."/.cvspass") and do {
# :pserver:cvs@mea.tmt.tele.fi:/cvsroot/zmailer Ah<Z
while(<H>) {
while (<H>) {
chomp;
s/^\/\d+\s+//;
my ($w,$p) = split(/\s/,$_,2);
if($w eq $rr or $w eq $rr2) {
if ($w eq $rr or $w eq $rr2) {
$pass = $p;
last;
}
@@ -202,7 +202,7 @@ sub conn {
$pass="A" unless $pass;
my ($s, $rep);
if($proxyhost) {
if ($proxyhost) {
# Use a HTTP Proxy. Only works for HTTP proxies that
# don't require user authentication
@@ -218,7 +218,7 @@ sub conn {
$rep = <$s>;
# The answer should look like 'HTTP/1.x 2yy ....'
if(!($rep =~ m#^HTTP/1\.. 2[0-9][0-9]#)) {
if (!($rep =~ m#^HTTP/1\.. 2[0-9][0-9]#)) {
die "Proxy connect: $rep\n";
}
# Skip up to the empty line of the proxy server output
@@ -239,7 +239,7 @@ sub conn {
$rep = <$s>;
if($rep ne "I LOVE YOU\n") {
if ($rep ne "I LOVE YOU\n") {
$rep="<unknown>" unless $rep;
die "AuthReply: $rep\n";
}
@@ -271,7 +271,7 @@ sub conn {
}
}
unless($pid) {
unless ($pid) {
$pr->writer();
$pw->reader();
dup2($pw->fileno(),0);
@@ -294,7 +294,7 @@ sub conn {
$self->{'socketo'}->flush();
chomp(my $rep=$self->readline());
if($rep !~ s/^Valid-requests\s*//) {
if ($rep !~ s/^Valid-requests\s*//) {
$rep="<unknown>" unless $rep;
die "Expected Valid-requests from server, but got: $rep\n";
}
@@ -306,14 +306,14 @@ sub conn {
}
sub readline {
my($self) = @_;
my ($self) = @_;
return $self->{'socketi'}->getline();
}
sub _file {
# Request a file with a given revision.
# Trial and error says this is a good way to do it. :-/
my($self,$fn,$rev) = @_;
my ($self,$fn,$rev) = @_;
$self->{'socketo'}->write("Argument -N\n") or return undef;
$self->{'socketo'}->write("Argument -P\n") or return undef;
# -kk: Linus' version doesn't use it - defaults to off
@@ -335,12 +335,12 @@ sub _file {
sub _line {
# Read a line from the server.
# ... except that 'line' may be an entire file. ;-)
my($self, $fh) = @_;
my ($self, $fh) = @_;
die "Not in lines" unless defined $self->{'lines'};
my $line;
my $res=0;
while(defined($line = $self->readline())) {
while (defined($line = $self->readline())) {
# M U gnupg-cvs-rep/AUTHORS
# Updated gnupg-cvs-rep/
# /daten/src/rsync/gnupg-cvs-rep/AUTHORS
@@ -349,7 +349,7 @@ sub _line {
# 0
# ok
if($line =~ s/^(?:Created|Updated) //) {
if ($line =~ s/^(?:Created|Updated) //) {
$line = $self->readline(); # path
$line = $self->readline(); # Entries line
my $mode = $self->readline(); chomp $mode;
@@ -360,12 +360,12 @@ sub _line {
die "Duh: Filesize $cnt" if $cnt !~ /^\d+$/;
$line="";
$res = $self->_fetchfile($fh, $cnt);
} elsif($line =~ s/^ //) {
} elsif ($line =~ s/^ //) {
print $fh $line;
$res += length($line);
} elsif($line =~ /^M\b/) {
} elsif ($line =~ /^M\b/) {
# output, do nothing
} elsif($line =~ /^Mbinary\b/) {
} elsif ($line =~ /^Mbinary\b/) {
my $cnt;
die "EOF from server after 'Mbinary'" unless defined ($cnt = $self->readline());
chomp $cnt;
@@ -374,12 +374,12 @@ sub _line {
$res += $self->_fetchfile($fh, $cnt);
} else {
chomp $line;
if($line eq "ok") {
if ($line eq "ok") {
# print STDERR "S: ok (".length($res).")\n";
return $res;
} elsif($line =~ s/^E //) {
} elsif ($line =~ s/^E //) {
# print STDERR "S: $line\n";
} elsif($line =~ /^(Remove-entry|Removed) /i) {
} elsif ($line =~ /^(Remove-entry|Removed) /i) {
$line = $self->readline(); # filename
$line = $self->readline(); # OK
chomp $line;
@@ -393,7 +393,7 @@ sub _line {
return undef;
}
sub file {
my($self,$fn,$rev) = @_;
my ($self,$fn,$rev) = @_;
my $res;
my ($fh, $name) = tempfile('gitcvs.XXXXXX',
@@ -417,7 +417,7 @@ sub _fetchfile {
my ($self, $fh, $cnt) = @_;
my $res = 0;
my $bufsize = 1024 * 1024;
while($cnt) {
while ($cnt) {
if ($bufsize > $cnt) {
$bufsize = $cnt;
}
@@ -438,7 +438,7 @@ my $cvs = CVSconn->new($opt_d, $cvs_tree);
sub pdate($) {
my($d) = @_;
my ($d) = @_;
m#(\d{2,4})/(\d\d)/(\d\d)\s(\d\d):(\d\d)(?::(\d\d))?#
or die "Unparseable date: $d\n";
my $y=$1; $y-=1900 if $y>1900;
@@ -446,22 +446,22 @@ sub pdate($) {
}
sub pmode($) {
my($mode) = @_;
my ($mode) = @_;
my $m = 0;
my $mm = 0;
my $um = 0;
for my $x(split(//,$mode)) {
if($x eq ",") {
if ($x eq ",") {
$m |= $mm&$um;
$mm = 0;
$um = 0;
} elsif($x eq "u") { $um |= 0700;
} elsif($x eq "g") { $um |= 0070;
} elsif($x eq "o") { $um |= 0007;
} elsif($x eq "r") { $mm |= 0444;
} elsif($x eq "w") { $mm |= 0222;
} elsif($x eq "x") { $mm |= 0111;
} elsif($x eq "=") { # do nothing
} elsif ($x eq "u") { $um |= 0700;
} elsif ($x eq "g") { $um |= 0070;
} elsif ($x eq "o") { $um |= 0007;
} elsif ($x eq "r") { $mm |= 0444;
} elsif ($x eq "w") { $mm |= 0222;
} elsif ($x eq "x") { $mm |= 0111;
} elsif ($x eq "=") { # do nothing
} else { die "Unknown mode: $mode\n";
}
}
@@ -485,7 +485,7 @@ sub get_headref ($$) {
my $git_dir = shift;
my $f = "$git_dir/refs/heads/$name";
if(open(my $fh, $f)) {
if (open(my $fh, $f)) {
chomp(my $r = <$fh>);
is_sha1($r) or die "Cannot get head id for $name ($r): $!";
return $r;
@@ -512,7 +512,7 @@ $orig_git_index = $ENV{GIT_INDEX_FILE} if exists $ENV{GIT_INDEX_FILE};
my %index; # holds filenames of one index per branch
unless(-d $git_dir) {
unless (-d $git_dir) {
system("git-init-db");
die "Cannot init the GIT db at $git_tree: $?\n" if $?;
system("git-read-tree");
@@ -531,7 +531,7 @@ unless(-d $git_dir) {
chomp ($last_branch = <F>);
$last_branch = basename($last_branch);
close(F);
unless($last_branch) {
unless ($last_branch) {
warn "Cannot read the last branch name: $! -- assuming 'master'\n";
$last_branch = "master";
}
@@ -542,7 +542,7 @@ unless(-d $git_dir) {
my $fmt = '($ref, $author) = (%(refname), %(author));';
open(H, "git-for-each-ref --perl --format='$fmt' refs/heads |") or
die "Cannot run git-for-each-ref: $!\n";
while(defined(my $entry = <H>)) {
while (defined(my $entry = <H>)) {
my ($ref, $author);
eval($entry) || die "cannot eval refs list: $@";
my ($head) = ($ref =~ m|^refs/heads/(.*)|);
@@ -572,7 +572,7 @@ unless ($opt_P) {
print "Running cvsps...\n" if $opt_v;
my $pid = open(CVSPS,"-|");
die "Cannot fork: $!\n" unless defined $pid;
unless($pid) {
unless ($pid) {
my @opt;
@opt = split(/,/,$opt_p) if defined $opt_p;
unshift @opt, '-z', $opt_z if defined $opt_z;
@@ -642,8 +642,8 @@ sub write_tree () {
return $tree;
}
my($patchset,$date,$author_name,$author_email,$branch,$ancestor,$tag,$logmsg);
my(@old,@new,@skipped,%ignorebranch);
my ($patchset,$date,$author_name,$author_email,$branch,$ancestor,$tag,$logmsg);
my (@old,@new,@skipped,%ignorebranch);
# commits that cvsps cannot place anywhere...
$ignorebranch{'#CVSPS_NO_BRANCH'} = 1;
@@ -684,7 +684,7 @@ sub commit {
foreach my $rx (@mergerx) {
next unless $logmsg =~ $rx && $1;
my $mparent = $1 eq 'HEAD' ? $opt_o : $1;
if(my $sha1 = get_headref($mparent, $git_dir)) {
if (my $sha1 = get_headref($mparent, $git_dir)) {
push @commit_args, '-p', $mparent;
print "Merge parent branch: $mparent\n" if $opt_v;
}
@@ -725,9 +725,9 @@ sub commit {
system("git-update-ref refs/heads/$branch $cid") == 0
or die "Cannot write branch $branch for update: $!\n";
if($tag) {
my($in, $out) = ('','');
my($xtag) = $tag;
if ($tag) {
my ($in, $out) = ('','');
my ($xtag) = $tag;
$xtag =~ s/\s+\*\*.*$//; # Remove stuff like ** INVALID ** and ** FUNKY **
$xtag =~ tr/_/\./ if ( $opt_u );
$xtag =~ s/[\/]/$opt_s/g;
@@ -762,25 +762,25 @@ sub commit {
};
my $commitcount = 1;
while(<CVS>) {
while (<CVS>) {
chomp;
if($state == 0 and /^-+$/) {
if ($state == 0 and /^-+$/) {
$state = 1;
} elsif($state == 0) {
} elsif ($state == 0) {
$state = 1;
redo;
} elsif(($state==0 or $state==1) and s/^PatchSet\s+//) {
} elsif (($state==0 or $state==1) and s/^PatchSet\s+//) {
$patchset = 0+$_;
$state=2;
} elsif($state == 2 and s/^Date:\s+//) {
} elsif ($state == 2 and s/^Date:\s+//) {
$date = pdate($_);
unless($date) {
unless ($date) {
print STDERR "Could not parse date: $_\n";
$state=0;
next;
}
$state=3;
} elsif($state == 3 and s/^Author:\s+//) {
} elsif ($state == 3 and s/^Author:\s+//) {
s/\s+$//;
if (/^(.*?)\s+<(.*)>/) {
($author_name, $author_email) = ($1, $2);
@@ -791,34 +791,34 @@ while(<CVS>) {
$author_name = $author_email = $_;
}
$state = 4;
} elsif($state == 4 and s/^Branch:\s+//) {
} elsif ($state == 4 and s/^Branch:\s+//) {
s/\s+$//;
s/[\/]/$opt_s/g;
$branch = $_;
$state = 5;
} elsif($state == 5 and s/^Ancestor branch:\s+//) {
} elsif ($state == 5 and s/^Ancestor branch:\s+//) {
s/\s+$//;
$ancestor = $_;
$ancestor = $opt_o if $ancestor eq "HEAD";
$state = 6;
} elsif($state == 5) {
} elsif ($state == 5) {
$ancestor = undef;
$state = 6;
redo;
} elsif($state == 6 and s/^Tag:\s+//) {
} elsif ($state == 6 and s/^Tag:\s+//) {
s/\s+$//;
if($_ eq "(none)") {
if ($_ eq "(none)") {
$tag = undef;
} else {
$tag = $_;
}
$state = 7;
} elsif($state == 7 and /^Log:/) {
} elsif ($state == 7 and /^Log:/) {
$logmsg = "";
$state = 8;
} elsif($state == 8 and /^Members:/) {
} elsif ($state == 8 and /^Members:/) {
$branch = $opt_o if $branch eq "HEAD";
if(defined $branch_date{$branch} and $branch_date{$branch} >= $date) {
if (defined $branch_date{$branch} and $branch_date{$branch} >= $date) {
# skip
print "skip patchset $patchset: $date before $branch_date{$branch}\n" if $opt_v;
$state = 11;
@@ -829,17 +829,17 @@ while(<CVS>) {
$state = 11;
next;
}
if($ancestor) {
if($ancestor eq $branch) {
if ($ancestor) {
if ($ancestor eq $branch) {
print STDERR "Branch $branch erroneously stems from itself -- changed ancestor to $opt_o\n";
$ancestor = $opt_o;
}
if(-f "$git_dir/refs/heads/$branch") {
if (-f "$git_dir/refs/heads/$branch") {
print STDERR "Branch $branch already exists!\n";
$state=11;
next;
}
unless(open(H,"$git_dir/refs/heads/$ancestor")) {
unless (open(H,"$git_dir/refs/heads/$ancestor")) {
print STDERR "Branch $ancestor does not exist!\n";
$ignorebranch{$branch} = 1;
$state=11;
@@ -847,7 +847,7 @@ while(<CVS>) {
}
chomp(my $id = <H>);
close(H);
unless(open(H,"> $git_dir/refs/heads/$branch")) {
unless (open(H,"> $git_dir/refs/heads/$branch")) {
print STDERR "Could not create branch $branch: $!\n";
$ignorebranch{$branch} = 1;
$state=11;
@@ -860,9 +860,9 @@ while(<CVS>) {
}
$last_branch = $branch if $branch ne $last_branch;
$state = 9;
} elsif($state == 8) {
} elsif ($state == 8) {
$logmsg .= "$_\n";
} elsif($state == 9 and /^\s+(.+?):(INITIAL|\d+(?:\.\d+)+)->(\d+(?:\.\d+)+)\s*$/) {
} elsif ($state == 9 and /^\s+(.+?):(INITIAL|\d+(?:\.\d+)+)->(\d+(?:\.\d+)+)\s*$/) {
# VERSION:1.96->1.96.2.1
my $init = ($2 eq "INITIAL");
my $fn = $1;
@@ -875,7 +875,7 @@ while(<CVS>) {
}
print "Fetching $fn v $rev\n" if $opt_v;
my ($tmpname, $size) = $cvs->file($fn,$rev);
if($size == -1) {
if ($size == -1) {
push(@old,$fn);
print "Drop $fn\n" if $opt_v;
} else {
@@ -893,14 +893,14 @@ while(<CVS>) {
push(@new,[$mode, $sha, $fn]); # may be resurrected!
}
unlink($tmpname);
} elsif($state == 9 and /^\s+(.+?):\d+(?:\.\d+)+->(\d+(?:\.\d+)+)\(DEAD\)\s*$/) {
} elsif ($state == 9 and /^\s+(.+?):\d+(?:\.\d+)+->(\d+(?:\.\d+)+)\(DEAD\)\s*$/) {
my $fn = $1;
$fn =~ s#^/+##;
push(@old,$fn);
print "Delete $fn\n" if $opt_v;
} elsif($state == 9 and /^\s*$/) {
} elsif ($state == 9 and /^\s*$/) {
$state = 10;
} elsif(($state == 9 or $state == 10) and /^-+$/) {
} elsif (($state == 9 or $state == 10) and /^-+$/) {
$commitcount++;
if ($opt_L && $commitcount > $opt_L) {
last;
@@ -910,11 +910,11 @@ while(<CVS>) {
system("git repack -a -d");
}
$state = 1;
} elsif($state == 11 and /^-+$/) {
} elsif ($state == 11 and /^-+$/) {
$state = 1;
} elsif(/^-+$/) { # end of unknown-line processing
} elsif (/^-+$/) { # end of unknown-line processing
$state = 1;
} elsif($state != 11) { # ignore stuff when skipping
} elsif ($state != 11) { # ignore stuff when skipping
print "* UNKNOWN LINE * $_\n";
}
}
@@ -943,7 +943,7 @@ if (defined $orig_git_index) {
}
# Now switch back to the branch we were in before all of this happened
if($orig_branch) {
if ($orig_branch) {
print "DONE.\n" if $opt_v;
if ($opt_i) {
exit 0;

View File

@@ -2822,7 +2822,9 @@ sub libsvn_connect {
SVN::Client::get_username_prompt_provider(
\&_username_prompt, 2),
]);
my $config = SVN::Core::config_get_config($_config_dir);
my $ra = SVN::Ra->new(url => $url, auth => $baton,
config => $config,
pool => SVN::Pool->new,
auth_provider_callbacks => $callbacks);
$ra->{svn_path} = $url;
@@ -2834,8 +2836,8 @@ sub libsvn_connect {
sub libsvn_dup_ra {
my ($ra) = @_;
SVN::Ra->new(map { $_ => $ra->{$_} }
qw/url auth auth_provider_callbacks repos_root svn_path/);
SVN::Ra->new(map { $_ => $ra->{$_} } qw/config url
auth auth_provider_callbacks repos_root svn_path/);
}
sub libsvn_get_file {

2
git.c
View File

@@ -260,7 +260,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
{ "rev-parse", cmd_rev_parse, RUN_SETUP },
{ "rm", cmd_rm, RUN_SETUP },
{ "runstatus", cmd_runstatus, RUN_SETUP },
{ "shortlog", cmd_shortlog, RUN_SETUP },
{ "shortlog", cmd_shortlog, RUN_SETUP | USE_PAGER },
{ "show-branch", cmd_show_branch, RUN_SETUP },
{ "show", cmd_show, RUN_SETUP | USE_PAGER },
{ "stripspace", cmd_stripspace },

View File

@@ -1261,7 +1261,7 @@ struct packed_git *find_sha1_pack(const unsigned char *sha1,
}
int sha1_object_info(const unsigned char *sha1, char *type, unsigned long *sizep)
static int sha1_loose_object_info(const unsigned char *sha1, char *type, unsigned long *sizep)
{
int status;
unsigned long mapsize, size;
@@ -1270,20 +1270,8 @@ int sha1_object_info(const unsigned char *sha1, char *type, unsigned long *sizep
char hdr[128];
map = map_sha1_file(sha1, &mapsize);
if (!map) {
struct pack_entry e;
if (!find_pack_entry(sha1, &e, NULL)) {
reprepare_packed_git();
if (!find_pack_entry(sha1, &e, NULL))
return error("unable to find %s", sha1_to_hex(sha1));
}
if (use_packed_git(e.p))
die("cannot map packed file");
status = packed_object_info(e.p, e.offset, type, sizep);
unuse_packed_git(e.p);
return status;
}
if (!map)
return error("unable to find %s", sha1_to_hex(sha1));
if (unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr)) < 0)
status = error("unable to unpack %s header",
sha1_to_hex(sha1));
@@ -1299,6 +1287,23 @@ int sha1_object_info(const unsigned char *sha1, char *type, unsigned long *sizep
return status;
}
int sha1_object_info(const unsigned char *sha1, char *type, unsigned long *sizep)
{
int status;
struct pack_entry e;
if (!find_pack_entry(sha1, &e, NULL)) {
reprepare_packed_git();
if (!find_pack_entry(sha1, &e, NULL))
return sha1_loose_object_info(sha1, type, sizep);
}
if (use_packed_git(e.p))
die("cannot map packed file");
status = packed_object_info(e.p, e.offset, type, sizep);
unuse_packed_git(e.p);
return status;
}
static void *read_packed_sha1(const unsigned char *sha1, char *type, unsigned long *size)
{
struct pack_entry e;