git-daemon
git-diff
git-diff-files
-git-diff-helper
git-diff-index
git-diff-stages
git-diff-tree
-git-export
git-fetch
git-fetch-pack
git-format-patch
git-resolve
git-rev-list
git-rev-parse
-git-rev-tree
git-revert
git-send-email
git-send-pack
git-verify-tag
git-whatchanged
git-write-tree
-#*.tar.gz
-#*.dsc
-#*.deb
-#git-core.spec
+git-core-*/?*
+*.tar.gz
+*.dsc
+*.deb
+git-core.spec
rm -f *.xml *.html *.1 *.7 howto-index.txt howto/*.html
%.html : %.txt
- asciidoc -b xhtml11 -d manpage $<
+ asciidoc -b xhtml11 -d manpage -f asciidoc.conf $<
%.1 %.7 : %.xml
xmlto man $<
%.xml : %.txt
- asciidoc -b docbook -d manpage $<
+ asciidoc -b docbook -d manpage -f asciidoc.conf $<
git.html: git.txt ../README
--- /dev/null
+## gitlink: macro
+#
+# Usage: gitlink:command[manpage-section]
+#
+# Note, {0} is the manpage section, while {target} is the command.
+#
+# Show GIT link as: <command>(<section>); if section is defined, else just show
+# the command.
+
+ifdef::backend-docbook[]
+[gitlink-inlinemacro]
+{0%{target}}
+{0#<citerefentry>}
+{0#<refentrytitle>{target}</refentrytitle><manvolnum>{0}</manvolnum>}
+{0#</citerefentry>}
+endif::backend-docbook[]
+
+ifdef::backend-xhtml11[]
+[gitlink-inlinemacro]
+<a href="{target}.html">{target}{0?({0})}</a>
+endif::backend-xhtml11[]
with a '-p' option, they do not produce the output described above;
instead they produce a patch file.
-The patch generation can be customized at two levels. This
-customization also applies to "git-diff-helper".
+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:
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
SEE ALSO
--------
-link:git-applypatch.html[git-applypatch].
+gitlink:git-applypatch[1].
Author
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
See Also
--------
-link:git-write-tree.html[git-write-tree]
+gitlink:git-write-tree[1]
Author
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
SYNOPSIS
--------
-'git-daemon' [--inetd | --port=n]
+'git-daemon' [--verbose] [--syslog] [--inetd | --port=n]
DESCRIPTION
-----------
--port::
Listen on an alternative port.
+--syslog::
+ Log to syslog instead of stderr. Note that this option does not imply
+ --verbose, thus by default only error conditions will be logged.
+
+--verbose::
+ Log details about the incoming connections and requested files.
+
Author
------
Written by Linus Torvalds <torvalds@osdl.org> and YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
+++ /dev/null
-git-diff-helper(1)
-==================
-v0.1, May 2005
-
-NAME
-----
-git-diff-helper - Generates patch format output for git-diff-*
-
-
-SYNOPSIS
---------
-'git-diff-helper' [-z] [-S<string>] [-O<orderfile>]
-
-DESCRIPTION
------------
-Reads output from "git-diff-index", "git-diff-tree" and "git-diff-files" and
-generates patch format output.
-
-OPTIONS
--------
--z::
- \0 line termination on input
-
--S<string>::
- Look for differences that contains the change in <string>.
-
---pickaxe-all::
- When -S finds a change, show all the changes in that
- changeset, not just the files that contains the change
- in <string>.
-
--O<orderfile>::
- Output the patch in the order specified in the
- <orderfile>, which has one shell glob pattern per line.
-
-See Also
---------
-The section on generating patches in link:git-diff-index.html[git-diff-index]
-
-
-Author
-------
-Written by Junio C Hamano <junkio@cox.net>
-
-
-Documentation
---------------
-Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel.org>.
-
-GIT
----
-Part of the link:git.html[git] suite
-
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
+++ /dev/null
-git-export(1)
-=============
-v0.1, May 2005
-
-NAME
-----
-git-export - Exports each commit and a diff against each of its parents
-
-
-SYNOPSIS
---------
-'git-export' top [base]
-
-DESCRIPTION
------------
-Exports each commit and diff against each of its parents, between
-top and base. If base is not specified it exports everything.
-
-
-Author
-------
-Written by Linus Torvalds <torvalds@osdl.org>
-
-Documentation
---------------
-Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel.org>.
-
-GIT
----
-Part of the link:git.html[git] suite
-
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
git-ls-files(1)
===============
-v0.1, May 2005
NAME
----
SYNOPSIS
--------
'git-ls-files' [-z] [-t]
- (--[cached|deleted|others|ignored|stage|unmerged|killed])\*
- (-[c|d|o|i|s|u|k])\*
+ (--[cached|deleted|others|ignored|stage|unmerged|killed|modified])\*
+ (-[c|d|o|i|s|u|k|m])\*
[-x <pattern>|--exclude=<pattern>]
[-X <file>|--exclude-from=<file>]
[--exclude-per-directory=<file>]
-d|--deleted::
Show deleted files in the output
+-m|--modified::
+ Show modified files in the output
+
-o|--others::
Show other files in the output
H cached
M unmerged
R removed/deleted
+ C modifed/changed
K to be killed
? other
See Also
--------
-link:git-read-tree.html[git-read-tree]
+gitlink:git-read-tree[1]
Author
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
SYNOPSIS
--------
-'git-read-tree' (<tree-ish> | [-m [-u]] <tree-ish1> [<tree-ish2> [<tree-ish3>]])
+'git-read-tree' (<tree-ish> | [-m [-u|-i]] <tree-ish1> [<tree-ish2> [<tree-ish3>]])
DESCRIPTION
After a successful merge, update the files in the work
tree with the result of the merge.
+-i::
+ Usually a merge requires the index file as well as the
+ files in the working tree are up to date with the
+ current head commit, in order not to lose local
+ changes. This flag disables the check with the working
+ tree and is meant to be used when creating a merge of
+ trees that are not directly related to the current
+ working tree status into a temporary index file.
+
+
<tree-ish#>::
The id of the tree object(s) to be read/merged.
See Also
--------
-link:git-write-tree.html[git-write-tree]; link:git-ls-files.html[git-ls-files]
+gitlink:git-write-tree[1]; gitlink:git-ls-files[1]
Author
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
SEE ALSO
--------
-link:git-send-pack.html[git-send-pack]
+gitlink:git-send-pack[1]
Author
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
+++ /dev/null
-git-rev-tree(1)
-===============
-v0.1, May 2005
-
-NAME
-----
-git-rev-tree - Provides the revision tree for one or more commits
-
-
-SYNOPSIS
---------
-'git-rev-tree' [--edges] [--cache <cache-file>] [^]<commit> [[^]<commit>]
-
-DESCRIPTION
------------
-Provides the revision tree for one or more commits.
-
-OPTIONS
--------
---edges::
- Show edges (ie places where the marking changes between parent
- and child)
-
---cache <cache-file>::
- Use the specified file as a cache from a previous git-rev-list run
- to speed things up. Note that this "cache" is totally different
- concept from the directory index. Also this option is not
- implemented yet.
-
-[^]<commit>::
- The commit id to trace (a leading caret means to ignore this
- commit-id and below)
-
-Output
-------
-
- <date> <commit>:<flags> [<parent-commit>:<flags> ]\*
-
-<date>::
- Date in 'seconds since epoch'
-
-<commit>::
- id of commit object
-
-<parent-commit>::
- id of each parent commit object (>1 indicates a merge)
-
-<flags>::
-
- The flags are read as a bitmask representing each commit
- provided on the commandline. eg: given the command:
-
- $ git-rev-tree <com1> <com2> <com3>
-
- The output:
-
- <date> <commit>:5
-
- means that <commit> is reachable from <com1>(1) and <com3>(4)
-
-A revtree can get quite large. "git-rev-tree" will eventually allow
-you to cache previous state so that you don't have to follow the whole
-thing down.
-
-So the change difference between two commits is literally
-
- git-rev-tree [commit-id1] > commit1-revtree
- git-rev-tree [commit-id2] > commit2-revtree
- join -t : commit1-revtree commit2-revtree > common-revisions
-
-(this is also how to find the most common parent - you'd look at just
-the head revisions - the ones that aren't referred to by other
-revisions - in "common-revision", and figure out the best one. I
-think.)
-
-
-Author
-------
-Written by Linus Torvalds <torvalds@osdl.org>
-
-Documentation
---------------
-Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel.org>.
-
-GIT
----
-Part of the link:git.html[git] suite
-
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
See Also
--------
-link:git-commit-tree.html[git-commit-tree]
-link:git-tag.html[git-tag]
+gitlink:git-commit-tree[1]
+gitlink:git-tag[1]
Author
------
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
The <<Discussion>> section below contains much useful definition and
clarification info - read that first. And of the commands, I suggest
-reading link:git-update-index.html[git-update-index] and
-link:git-read-tree.html[git-read-tree] first - I wish I had!
+reading gitlink:git-update-index[1] and
+gitlink:git-read-tree[1] first - I wish I had!
If you are migrating from CVS, link:cvs-migration.html[cvs migration]
document may be helpful after you finish the tutorial.
Manipulation commands
~~~~~~~~~~~~~~~~~~~~~
-link:git-apply.html[git-apply]::
+gitlink:git-apply[1]::
Reads a "diff -up1" or git generated patch file and
applies it to the working tree.
-link:git-checkout-index.html[git-checkout-index]::
+gitlink:git-checkout-index[1]::
Copy files from the cache to the working directory
Previously this command was known as git-checkout-cache.
-link:git-commit-tree.html[git-commit-tree]::
+gitlink:git-commit-tree[1]::
Creates a new commit object
-link:git-hash-object.html[git-hash-object]::
+gitlink:git-hash-object[1]::
Computes the object ID from a file.
-link:git-init-db.html[git-init-db]::
+gitlink:git-init-db[1]::
Creates an empty git object database
-link:git-merge-index.html[git-merge-index]::
+gitlink:git-merge-index[1]::
Runs a merge for files needing merging
Previously this command was known as git-merge-cache.
-link:git-mktag.html[git-mktag]::
+gitlink:git-mktag[1]::
Creates a tag object
-link:git-pack-objects.html[git-pack-objects]::
+gitlink:git-pack-objects[1]::
Creates a packed archive of objects.
-link:git-prune-packed.html[git-prune-packed]::
+gitlink:git-prune-packed[1]::
Remove extra objects that are already in pack files.
-link:git-read-tree.html[git-read-tree]::
+gitlink:git-read-tree[1]::
Reads tree information into the directory cache
-link:git-unpack-objects.html[git-unpack-objects]::
+gitlink:git-unpack-objects[1]::
Unpacks objects out of a packed archive.
-link:git-update-index.html[git-update-index]::
+gitlink:git-update-index[1]::
Modifies the index or directory cache
Previously this command was known as git-update-cache.
-link:git-write-tree.html[git-write-tree]::
+gitlink:git-write-tree[1]::
Creates a tree from the current cache
Interrogation commands
~~~~~~~~~~~~~~~~~~~~~~
-link:git-cat-file.html[git-cat-file]::
+gitlink:git-cat-file[1]::
Provide content or type information for repository objects
-link:git-diff-index.html[git-diff-index]::
+gitlink:git-diff-index[1]::
Compares content and mode of blobs between the cache and repository
Previously this command was known as git-diff-cache.
-link:git-diff-files.html[git-diff-files]::
+gitlink:git-diff-files[1]::
Compares files in the working tree and the cache
-link:git-diff-stages.html[git-diff-stages]::
+gitlink:git-diff-stages[1]::
Compares two "merge stages" in the index file.
-link:git-diff-tree.html[git-diff-tree]::
+gitlink:git-diff-tree[1]::
Compares the content and mode of blobs found via two tree objects
-link:git-export.html[git-export]::
- Exports each commit and a diff against each of its parents
-
-link:git-fsck-objects.html[git-fsck-objects]::
+gitlink:git-fsck-objects[1]::
Verifies the connectivity and validity of the objects in the database
Previously this command was known as git-fsck-cache.
-link:git-ls-files.html[git-ls-files]::
+gitlink:git-ls-files[1]::
Information about files in the cache/working directory
-link:git-ls-tree.html[git-ls-tree]::
+gitlink:git-ls-tree[1]::
Displays a tree object in human readable form
-link:git-merge-base.html[git-merge-base]::
+gitlink:git-merge-base[1]::
Finds as good a common ancestor as possible for a merge
-link:git-rev-list.html[git-rev-list]::
+gitlink:git-rev-list[1]::
Lists commit objects in reverse chronological order
-link:git-rev-tree.html[git-rev-tree]::
- Provides the revision tree for one or more commits
-
-link:git-show-index.html[git-show-index]::
+gitlink:git-show-index[1]::
Displays contents of a pack idx file.
-link:git-tar-tree.html[git-tar-tree]::
+gitlink:git-tar-tree[1]::
Creates a tar archive of the files in the named tree
-link:git-unpack-file.html[git-unpack-file]::
+gitlink:git-unpack-file[1]::
Creates a temporary file with a blob's contents
-link:git-var.html[git-var]::
+gitlink:git-var[1]::
Displays a git logical variable
-link:git-verify-pack.html[git-verify-pack]::
+gitlink:git-verify-pack[1]::
Validates packed GIT archive files
The interrogate commands may create files - and you can force them to
Synching repositories
~~~~~~~~~~~~~~~~~~~~~
-link:git-clone-pack.html[git-clone-pack]::
+gitlink:git-clone-pack[1]::
Clones a repository into the current repository (engine
for ssh and local transport)
-link:git-fetch-pack.html[git-fetch-pack]::
+gitlink:git-fetch-pack[1]::
Updates from a remote repository.
-link:git-http-fetch.html[git-http-fetch]::
+gitlink:git-http-fetch[1]::
Downloads a remote GIT repository via HTTP
Previously this command was known as git-http-pull.
-link:git-local-fetch.html[git-local-fetch]::
+gitlink:git-local-fetch[1]::
Duplicates another GIT repository on a local system
Previously this command was known as git-local-pull.
-link:git-peek-remote.html[git-peek-remote]::
+gitlink:git-peek-remote[1]::
Lists references on a remote repository using upload-pack protocol.
-link:git-receive-pack.html[git-receive-pack]::
+gitlink:git-receive-pack[1]::
Invoked by 'git-send-pack' to receive what is pushed to it.
-link:git-send-pack.html[git-send-pack]::
+gitlink:git-send-pack[1]::
Pushes to a remote repository, intelligently.
-link:git-ssh-fetch.html[git-ssh-fetch]::
+gitlink:git-ssh-fetch[1]::
Pulls from a remote repository over ssh connection
Previously this command was known as git-ssh-pull.
-link:git-ssh-upload.html[git-ssh-upload]::
+gitlink:git-ssh-upload[1]::
Helper "server-side" program used by git-ssh-fetch
Previously this command was known as git-ssh-push.
-link:git-update-server-info.html[git-update-server-info]::
+gitlink:git-update-server-info[1]::
Updates auxiliary information on a dumb server to help
clients discover references and packs on it.
-link:git-upload-pack.html[git-upload-pack]::
+gitlink:git-upload-pack[1]::
Invoked by 'git-clone-pack' and 'git-fetch-pack' to push
what are asked for.
Porcelain-ish Commands
----------------------
-link:git-add.html[git-add]::
+gitlink:git-add[1]::
Add paths to the index file.
Previously this command was known as git-add-script.
-link:git-applymbox.html[git-applymbox]::
+gitlink:git-applymbox[1]::
Apply patches from a mailbox.
-link:git-bisect.html[git-bisect]::
+gitlink:git-bisect[1]::
Find the change that introduced a bug.
Previously this command was known as git-bisect-script.
-link:git-branch.html[git-branch]::
+gitlink:git-branch[1]::
Create and Show branches.
Previously this command was known as git-branch-script.
-link:git-checkout.html[git-checkout]::
+gitlink:git-checkout[1]::
Checkout and switch to a branch.
Previously this command was known as git-checkout-script.
-link:git-cherry-pick.html[git-cherry-pick]::
+gitlink:git-cherry-pick[1]::
Cherry-pick the effect of an existing commit.
Previously this command was known as git-cherry-pick-script.
-link:git-clone.html[git-clone]::
+gitlink:git-clone[1]::
Clones a repository into a new directory.
Previously this command was known as git-clone-script.
-link:git-commit.html[git-commit]::
+gitlink:git-commit[1]::
Record changes to the repository.
Previously this command was known as git-commit-script.
-link:git-diff.html[git-diff]::
+gitlink:git-diff[1]::
Show changes between commits, commit and working tree, etc.
Previously this command was known as git-diff-script.
-link:git-fetch.html[git-fetch]::
+gitlink:git-fetch[1]::
Download from a remote repository via various protocols.
Previously this command was known as git-fetch-script.
-link:git-format-patch.html[git-format-patch]::
+gitlink:git-format-patch[1]::
Prepare patches for e-mail submission.
Previously this command was known as git-format-patch-script.
-link:git-grep.html[git-grep]::
+gitlink:git-grep[1]::
Print lines matching a pattern
-link:git-log.html[git-log]::
+gitlink:git-log[1]::
Shows commit logs.
Previously this command was known as git-log-script.
-link:git-ls-remote.html[git-ls-remote]::
+gitlink:git-ls-remote[1]::
Shows references in a remote or local repository.
Previously this command was known as git-ls-remote-script.
-link:git-merge.html[git-merge]::
+gitlink:git-merge[1]::
Grand unified merge driver.
-link:git-octopus.html[git-octopus]::
+gitlink:git-octopus[1]::
Merge more than two commits.
Previously this command was known as git-octopus-script.
-link:git-pull.html[git-pull]::
+gitlink:git-pull[1]::
Fetch from and merge with a remote repository.
Previously this command was known as git-pull-script.
-link:git-push.html[git-push]::
+gitlink:git-push[1]::
Update remote refs along with associated objects.
Previously this command was known as git-push-script.
-link:git-rebase.html[git-rebase]::
+gitlink:git-rebase[1]::
Rebase local commits to new upstream head.
Previously this command was known as git-rebase-script.
-link:git-rename.html[git-rename]::
+gitlink:git-rename[1]::
Rename files and directories.
Previously this command was known as git-rename-script.
-link:git-repack.html[git-repack]::
+gitlink:git-repack[1]::
Pack unpacked objects in a repository.
Previously this command was known as git-repack-script.
-link:git-reset.html[git-reset]::
+gitlink:git-reset[1]::
Reset current HEAD to the specified state.
Previously this command was known as git-reset-script.
-link:git-resolve.html[git-resolve]::
+gitlink:git-resolve[1]::
Merge two commits.
Previously this command was known as git-resolve-script.
-link:git-revert.html[git-revert]::
+gitlink:git-revert[1]::
Revert an existing commit.
Previously this command was known as git-revert-script.
-link:git-shortlog.html[git-shortlog]::
+gitlink:git-shortlog[1]::
Summarizes 'git log' output.
-link:git-show-branch.html[git-show-branch]::
+gitlink:git-show-branch[1]::
Show branches and their commits.
-link:git-status.html[git-status]::
+gitlink:git-status[1]::
Shows the working tree status.
Previously this command was known as git-status-script.
-link:git-verify-tag.html[git-verify-tag]::
+gitlink:git-verify-tag[1]::
Check the GPG signature of tag.
Previously this command was known as git-verify-tag-script.
-link:git-whatchanged.html[git-whatchanged]::
+gitlink:git-whatchanged[1]::
Shows commit logs and differences they introduce.
------------------
Manipulators:
-link:git-applypatch.html[git-applypatch]::
+gitlink:git-applypatch[1]::
Apply one patch extracted from an e-mail.
-link:git-archimport.html[git-archimport]::
+gitlink:git-archimport[1]::
Import an arch repository into git.
Previously this command was known as git-archimport-script.
-link:git-convert-objects.html[git-convert-objects]::
+gitlink:git-convert-objects[1]::
Converts old-style GIT repository
Previously this command was known as git-convert-cache.
-link:git-cvsimport.html[git-cvsimport]::
+gitlink:git-cvsimport[1]::
Salvage your data out of another SCM people love to hate.
Previously this command was known as git-cvsimport-script.
-link:git-merge-one-file.html[git-merge-one-file]::
+gitlink:git-merge-one-file[1]::
The standard helper program to use with "git-merge-index"
Previously this command was known as git-merge-one-file-script.
-link:git-prune.html[git-prune]::
+gitlink:git-prune[1]::
Prunes all unreachable objects from the object database
Previously this command was known as git-prune-script.
-link:git-relink.html[git-relink]::
+gitlink:git-relink[1]::
Hardlink common objects in local repositories.
Previously this command was known as git-relink-script.
-link:git-sh-setup.html[git-sh-setup]::
+gitlink:git-sh-setup[1]::
Common git shell script setup code.
Previously this command was known as git-sh-setup-script.
-link:git-tag.html[git-tag]::
+gitlink:git-tag[1]::
An example script to create a tag object signed with GPG
Previously this command was known as git-tag-script.
Interrogators:
-link:git-cherry.html[git-cherry]::
+gitlink:git-cherry[1]::
Find commits not merged upstream.
-link:git-count-objects.html[git-count-objects]::
+gitlink:git-count-objects[1]::
Count unpacked number of objects and their disk consumption.
Previously this command was known as git-count-objects-script.
-link:git-daemon.html[git-daemon]::
+gitlink:git-daemon[1]::
A really simple server for GIT repositories.
-link:git-diff-helper.html[git-diff-helper]::
- Generates patch format output for git-diff-*
-
-link:git-get-tar-commit-id.html[git-get-tar-commit-id]::
+gitlink:git-get-tar-commit-id[1]::
Extract commit ID from an archive created using git-tar-tree.
-link:git-mailinfo.html[git-mailinfo]::
+gitlink:git-mailinfo[1]::
Extracts patch from a single e-mail message.
-link:git-mailsplit.html[git-mailsplit]::
+gitlink:git-mailsplit[1]::
git-mailsplit.
-link:git-patch-id.html[git-patch-id]::
+gitlink:git-patch-id[1]::
Compute unique ID for a patch.
-link:git-parse-remote.html[git-parse-remote]::
+gitlink:git-parse-remote[1]::
Routines to help parsing $GIT_DIR/remotes/
Previously this command was known as git-parse-remote-script.
-link:git-request-pull.html[git-request-pull]::
+gitlink:git-request-pull[1]::
git-request-pull.
Previously this command was known as git-request-pull-script.
-link:git-rev-parse.html[git-rev-parse]::
+gitlink:git-rev-parse[1]::
Pick out and massage parameters.
-link:git-send-email.html[git-send-email]::
+gitlink:git-send-email[1]::
Send patch e-mails out of "format-patch --mbox" output.
Previously this command was known as git-send-email-script.
-link:git-stripspace.html[git-stripspace]::
+gitlink:git-stripspace[1]::
Filter out empty lines.
Commands not yet documented
---------------------------
-link:gitk.html[gitk]::
+gitlink:gitk[1]::
gitk.
'GIT_AUTHOR_DATE'::
'GIT_COMMITTER_NAME'::
'GIT_COMMITTER_EMAIL'::
- see link:git-commit-tree.html[git-commit-tree]
+ see gitlink:git-commit-tree[1]
git Diffs
~~~~~~~~~
'GIT_DIFF_OPTS'::
'GIT_EXTERNAL_DIFF'::
see the "generating patches" section in :
- link:git-diff-index.html[git-diff-index];
- link:git-diff-files.html[git-diff-files];
- link:git-diff-tree.html[git-diff-tree]
+ gitlink:git-diff-index[1];
+ gitlink:git-diff-files[1];
+ gitlink:git-diff-tree[1]
Discussion[[Discussion]]
------------------------
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
GIT
---
-Part of the link:git.html[git] suite
+Part of the gitlink:git[7] suite
rb=$(tput setab 1)
restore=$(tput setab 9)
-if [ `git-rev-tree release ^test | wc -c` -gt 0 ]
+if [ `git-rev-list release ^test | wc -c` -gt 0 ]
then
echo $rb Warning: commits in release that are not in test $restore
git-whatchanged release ^test
status=
for ref in test release linus
do
- if [ `git-rev-tree $branch ^$ref | wc -c` -gt 0 ]
+ if [ `git-rev-list $branch ^$ref | wc -c` -gt 0 ]
then
status=$status${ref:0:1}
fi
for entries that don't change, and allowing -u to make the minimum
required changes to the working tree to have it match.
+Entries marked '+' have stat information. Spaces marked '*' don't
+affect the result.
+
index tree result
-----------------------
* (empty) (empty)
Two-way merge
-------------
+It is permitted for the index to lack an entry; this does not prevent
+any case from applying.
+
+If the index exists, it is an error for it not to match either the old
+or the result.
+
+If multiple cases apply, the one used is listed first.
+
+A result which changes the index is an error if the index is not empty
+and not up-to-date.
+
+Entries marked '+' have stat information. Spaces marked '*' don't
+affect the result.
+ case index old new result
+ -------------------------------------
+ 0/2 (empty) * (empty) (empty)
+ 1/3 (empty) * new new
+ 4/5 index+ (empty) (empty) index+
+ 6/7 index+ (empty) index index+
+ 10 index+ index (empty) (empty)
+ 14/15 index+ old old index+
+ 18/19 index+ old index index+
+ 20 index+ index new new
Three-way merge
---------------
*empty* means that the tree must not have a directory-file conflict
with the entry.
-For multiple ancestors or remotes, a '+' means that this case applies
-even if only one ancestor or remote fits; normally, all of the
-ancestors or remotes must be the same.
+For multiple ancestors, a '+' means that this case applies even if
+only one ancestor or remote fits; a '^' means all of the ancestors
+must be the same.
case ancest head remote result
----------------------------------------
1 (empty)+ (empty) (empty) (empty)
2ALT (empty)+ *empty* remote remote
-2ALT (empty)+ *empty* remote remote
2 (empty)^ (empty) remote no merge
3ALT (empty)+ head *empty* head
3 (empty)^ head (empty) no merge
4 (empty)^ head remote no merge
5ALT * head head head
-6 ancest^ (empty) (empty) no merge
-8ALT ancest (empty) ancest (empty)
+6 ancest+ (empty) (empty) no merge
+8 ancest^ (empty) ancest no merge
7 ancest+ (empty) remote no merge
+10 ancest^ ancest (empty) no merge
9 ancest+ head (empty) no merge
-10ALT ancest ancest (empty) (empty)
-11 ancest+ head remote no merge
16 anc1/anc2 anc1 anc2 no merge
13 ancest+ head ancest head
14 ancest+ ancest remote remote
-14ALT ancest+ ancest remote remote
+11 ancest+ head remote no merge
Only #2ALT and #3ALT use *empty*, because these are the only cases
where there can be conflicts that didn't exist before. Note that we
multiple times), and the right answer depends on looking at crossings
of history or common ancestors of the ancestors.
-The status as of Sep 5 is that multiple remotes are not supported
\ No newline at end of file
+Note that, between #6, #7, #9, and #11, all cases not otherwise
+covered are handled in this table.
+
+For #8 and #10, there is alternative behavior, not currently
+implemented, where the result is (empty). As currently implemented,
+the automatic merge will generally give this effect.
commit itself (`git-commit`).
-Checking it out
----------------
+Inspecting Changes
+------------------
While creating changes is useful, it's even more useful if you can tell
later what changed. The most useful command for this is another of the
means they are now part of the `master` branch. Only the "Some
work" commit has the plus `+` character in the second column,
because `mybranch` has not been merged to incorporate these
-commits from the master branch.
+commits from the master branch. The string inside brackets
+before the commit log message is a short name you can use to
+name the commit. In the above example, 'master' and 'mybranch'
+are branch heads. 'master~1' is the first parent of 'master'
+branch head. Please see 'git-rev-parse' documentation if you
+see more complex cases.
Now, let's pretend you are the one who did all the work in
`mybranch`, and the fruit of your hard work has finally been merged
back before you push your work when it happens.
+Bundling your work together
+---------------------------
+
+It is likely that you will be working on more than one thing at
+a time. It is easy to use those more-or-less independent tasks
+using branches with git.
+
+We have already seen how branches work in a previous example,
+with "fun and work" example using two branches. The idea is the
+same if there are more than two branches. Let's say you started
+out from "master" head, and have some new code in the "master"
+branch, and two independent fixes in the "commit-fix" and
+"diff-fix" branches:
+
+------------
+$ git show-branch
+! [commit-fix] Fix commit message normalization.
+ ! [diff-fix] Fix rename detection.
+ * [master] Release candidate #1
+---
+ + [diff-fix] Fix rename detection.
+ + [diff-fix~1] Better common substring algorithm.
++ [commit-fix] Fix commit message normalization.
+ + [master] Release candidate #1
++++ [diff-fix~2] Pretty-print messages.
+------------
+
+Both fixes are tested well, and at this point, you want to merge
+in both of them. You could merge in 'diff-fix' first and then
+'commit-fix' next, like this:
+
+------------
+$ git resolve master diff-fix 'Merge fix in diff-fix'
+$ git resolve master commit-fix 'Merge fix in commit-fix'
+------------
+
+Which would result in:
+
+------------
+$ git show-branch
+! [commit-fix] Fix commit message normalization.
+ ! [diff-fix] Fix rename detection.
+ * [master] Merge fix in commit-fix
+---
+ + [master] Merge fix in commit-fix
++ + [commit-fix] Fix commit message normalization.
+ + [master~1] Merge fix in diff-fix
+ ++ [diff-fix] Fix rename detection.
+ ++ [diff-fix~1] Better common substring algorithm.
+ + [master~2] Release candidate #1
++++ [master~3] Pretty-print messages.
+------------
+
+However, there is no particular reason to merge in one branch
+first and the other next, when what you have are a set of truly
+independent changes (if the order mattered, then they are not
+independent by definition). You could instead merge those two
+branches into the current branch at once. First let's undo what
+we just did and start over. We would want to get the master
+branch before these two merges by resetting it to 'master~2':
+
+------------
+$ git reset --hard master~2
+------------
+
+You can make sure 'git show-branch' matches the state before
+those two 'git resolve' you just did. Then, instead of running
+two 'git resolve' commands in a row, you would pull these two
+branch heads (this is known as 'making an Octopus'):
+
+------------
+$ git pull . commit-fix diff-fix
+$ git show-branch
+! [commit-fix] Fix commit message normalization.
+ ! [diff-fix] Fix rename detection.
+ * [master] Octopus merge of branches 'diff-fix' and 'commit-fix'
+---
+ + [master] Octopus merge of branches 'diff-fix' and 'commit-fix'
++ + [commit-fix] Fix commit message normalization.
+ ++ [diff-fix] Fix rename detection.
+ ++ [diff-fix~1] Better common substring algorithm.
+ + [master~1] Release candidate #1
++++ [master~2] Pretty-print messages.
+------------
+
+Note that you should not do Octopus because you can. An octopus
+is a valid thing to do and often makes it easier to view the
+commit history if you are pulling more than two independent
+changes at the same time. However, if you have merge conflicts
+with any of the branches you are merging in and need to hand
+resolve, that is an indication that the development happened in
+those branches were not independent after all, and you should
+merge two at a time, documenting how you resolved the conflicts,
+and the reason why you preferred changes made in one side over
+the other. Otherwise it would make the project history harder
+to follow, not easier.
+
[ to be continued.. cvsimports ]
# Define NO_CURL if you do not have curl installed. git-http-pull is not
# built, and you cannot use http:// and https:// transports.
#
+# Define CURLDIR=/foo/bar if your curl header and library files are in
+# /foo/bar/include and /foo/bar/lib directories.
+#
# Define NO_STRCASESTR if you don't have strcasestr.
#
# Define PPC_SHA1 environment variable when running make to make use of
# a bundled SHA1 routine optimized for PowerPC.
#
+# Define ARM_SHA1 environment variable when running make to make use of
+# a bundled SHA1 routine optimized for ARM.
+#
# Define NEEDS_SSL_WITH_CRYPTO if you need -lcrypto with -lssl (Darwin).
#
# Define NEEDS_LIBICONV if linking with libc is not enough (Darwin).
# Define NEEDS_SOCKET if linking with libc is not enough (SunOS,
# Patrick Mauritz).
#
-# Define NO_GETDOMAINNAME if your library lack it (SunOS, Patrick Mauritz).
-#
# Define WITH_OWN_SUBPROCESS_PY if you want to use with python 2.3.
#
# Define COLLISION_CHECK below if you believe that SHA1's
# DEFINES += -DUSE_STDEV
-GIT_VERSION = 0.99.7
+GIT_VERSION = 0.99.7.GIT
CFLAGS = -g -O2 -Wall
ALL_CFLAGS = $(CFLAGS) $(PLATFORM_DEFINES) $(DEFINES)
CC = gcc
AR = ar
+TAR = tar
INSTALL = install
RPMBUILD = rpmbuild
SCRIPT_PERL = \
git-archimport.perl git-cvsimport.perl git-relink.perl \
- git-rename.perl git-shortlog.perl
+ git-rename.perl git-shortlog.perl git-fmt-merge-msg.perl
SCRIPT_PYTHON = \
git-merge-recursive.py
git-apply git-cat-file \
git-checkout-index git-clone-pack git-commit-tree \
git-convert-objects git-diff-files \
- git-diff-helper git-diff-index git-diff-stages \
- git-diff-tree git-export git-fetch-pack git-fsck-objects \
+ git-diff-index git-diff-stages \
+ git-diff-tree git-fetch-pack git-fsck-objects \
git-hash-object git-init-db \
git-local-fetch git-ls-files git-ls-tree git-merge-base \
git-merge-index git-mktag git-pack-objects git-patch-id \
git-peek-remote git-prune-packed git-read-tree \
git-receive-pack git-rev-list git-rev-parse \
- git-rev-tree git-send-pack git-show-branch \
+ git-send-pack git-show-branch \
git-show-index git-ssh-fetch \
git-ssh-upload git-tar-tree git-unpack-file \
git-unpack-objects git-update-index git-update-server-info \
SCRIPT_PERL += git-send-email.perl
endif
-ifndef NO_CURL
- PROGRAMS += git-http-fetch
-endif
-
LIB_FILE=libgit.a
LIB_H = \
LIBS = $(LIB_FILE)
LIBS += -lz
+#
+# Platform specific tweaks
+#
ifeq ($(shell uname -s),Darwin)
NEEDS_SSL_WITH_CRYPTO = YesPlease
NEEDS_LIBICONV = YesPlease
ifeq ($(shell uname -s),SunOS)
NEEDS_SOCKET = YesPlease
NEEDS_NSL = YesPlease
+ SHELL_PATH = /bin/bash
+ NO_STRCASESTR = YesPlease
+ CURLDIR = /opt/sfw
+ INSTALL = ginstall
+ TAR = gtar
PLATFORM_DEFINES += -D__EXTENSIONS__
endif
+ifneq (,$(findstring arm,$(shell uname -m)))
+ ARM_SHA1 = YesPlease
+endif
+
+ifndef NO_CURL
+ ifdef CURLDIR
+ # This is still problematic -- gcc does not want -R.
+ CFLAGS += -I$(CURLDIR)/include
+ CURL_LIBCURL = -L$(CURLDIR)/lib -R$(CURLDIR)/lib -lcurl
+ else
+ CURL_LIBCURL = -lcurl
+ endif
+ PROGRAMS += git-http-fetch
+endif
ifndef SHELL_PATH
SHELL_PATH = /bin/sh
else
LIB_4_ICONV =
endif
-ifdef MOZILLA_SHA1
- SHA1_HEADER = "mozilla-sha1/sha1.h"
- LIB_OBJS += mozilla-sha1/sha1.o
-else
- ifdef PPC_SHA1
- SHA1_HEADER = "ppc/sha1.h"
- LIB_OBJS += ppc/sha1.o ppc/sha1ppc.o
- else
- SHA1_HEADER = <openssl/sha.h>
- LIBS += $(LIB_4_CRYPTO)
- endif
-endif
ifdef NEEDS_SOCKET
LIBS += -lsocket
SIMPLE_LIB += -lsocket
LIB_OBJS += compat/strcasestr.o
endif
+ifdef PPC_SHA1
+ SHA1_HEADER = "ppc/sha1.h"
+ LIB_OBJS += ppc/sha1.o ppc/sha1ppc.o
+else
+ifdef ARM_SHA1
+ SHA1_HEADER = "arm/sha1.h"
+ LIB_OBJS += arm/sha1.o arm/sha1_arm.o
+else
+ifdef MOZILLA_SHA1
+ SHA1_HEADER = "mozilla-sha1/sha1.h"
+ LIB_OBJS += mozilla-sha1/sha1.o
+else
+ SHA1_HEADER = <openssl/sha.h>
+ LIBS += $(LIB_4_CRYPTO)
+endif
+endif
+endif
+
DEFINES += '-DSHA1_HEADER=$(SHA1_HEADER)'
SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \
$(patsubst %.py,%,$(SCRIPT_PYTHON)) \
gitk
+export TAR INSTALL DESTDIR
### Build rules
all: $(PROGRAMS) $(SCRIPTS)
git: git.sh Makefile
rm -f $@+ $@
- sed -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' <$@.sh >$@+
+ sed -e '1s|#!.*/sh|#!$(SHELL_PATH)|' \
+ -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' <$@.sh >$@+
chmod +x $@+
mv $@+ $@
git-ssh-pull: rsh.o fetch.o
git-ssh-push: rsh.o
-git-http-fetch: LIBS += -lcurl
+git-http-fetch: LIBS += $(CURL_LIBCURL)
git-rev-list: LIBS += $(OPENSSL_LIBSSL)
init-db.o: init-db.c
$(INSTALL) -d -m755 $(DESTDIR)$(bindir)
$(INSTALL) $(PROGRAMS) $(SCRIPTS) $(DESTDIR)$(bindir)
$(INSTALL) git-revert $(DESTDIR)$(bindir)/git-cherry-pick
- sh ./cmd-rename.sh $(DESTDIR)$(bindir)
$(MAKE) -C templates install
$(INSTALL) -d -m755 $(DESTDIR)$(GIT_PYTHON_DIR)
$(INSTALL) $(PYMODULES) $(DESTDIR)$(GIT_PYTHON_DIR)
./git-tar-tree HEAD $(GIT_TARNAME) > $(GIT_TARNAME).tar
@mkdir -p $(GIT_TARNAME)
@cp git-core.spec $(GIT_TARNAME)
- tar rf $(GIT_TARNAME).tar $(GIT_TARNAME)/git-core.spec
+ $(TAR) rf $(GIT_TARNAME).tar $(GIT_TARNAME)/git-core.spec
@rm -rf $(GIT_TARNAME)
gzip -f -9 $(GIT_TARNAME).tar
deb: dist
rm -rf $(GIT_TARNAME)
- tar zxf $(GIT_TARNAME).tar.gz
+ $(TAR) zxf $(GIT_TARNAME).tar.gz
dpkg-source -b $(GIT_TARNAME)
cd $(GIT_TARNAME) && fakeroot debian/rules binary
### Cleaning rules
clean:
- rm -f *.o mozilla-sha1/*.o ppc/*.o $(PROGRAMS) $(LIB_FILE)
+ rm -f *.o mozilla-sha1/*.o ppc/*.o compat/*.o $(PROGRAMS) $(LIB_FILE)
rm -f $(filter-out gitk,$(SCRIPTS))
- rm -f git-core.spec
+ rm -f git-core.spec *.pyc *.pyo
rm -rf $(GIT_TARNAME)
rm -f $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz
rm -f git-core_$(GIT_VERSION)-*.deb git-core_$(GIT_VERSION)-*.dsc
rm -f git-tk_$(GIT_VERSION)-*.deb
$(MAKE) -C Documentation/ clean
- $(MAKE) -C templates/ clean
+ $(MAKE) -C templates clean
$(MAKE) -C t/ clean
directory tree, and renaming a file does not change the object that
file is associated with in any way.
-A blob is typically created when link:git-update-index.html[git-update-index]
-is run, and its data can be accessed by link:git-cat-file.html[git-cat-file].
+A blob is typically created when gitlink:git-update-index[1]
+is run, and its data can be accessed by gitlink:git-cat-file[1].
Tree Object
~~~~~~~~~~~
noticing that the blob stayed the same. However, renames with data
changes need a smarter "diff" implementation.
-A tree is created with link:git-write-tree.html[git-write-tree] and
-its data can be accessed by link:git-ls-tree.html[git-ls-tree].
-Two trees can be compared with link:git-diff-tree.html[git-diff-tree].
+A tree is created with gitlink:git-write-tree[1] and
+its data can be accessed by gitlink:git-ls-tree[1].
+Two trees can be compared with gitlink:git-diff-tree[1].
Commit Object
~~~~~~~~~~~~~
of the parents), and describing that makes no sense in this idiotic
file manager.
-A commit is created with link:git-commit-tree.html[git-commit-tree] and
-its data can be accessed by link:git-cat-file.html[git-cat-file].
+A commit is created with gitlink:git-commit-tree[1] and
+its data can be accessed by gitlink:git-cat-file[1].
Trust
~~~~~
integrity; the trust framework (and signature provision and
verification) has to come from outside.
-A tag is created with link:git-mktag.html[git-mktag],
-its data can be accessed by link:git-cat-file.html[git-cat-file],
+A tag is created with gitlink:git-mktag[1],
+its data can be accessed by gitlink:git-cat-file[1],
and the signature can be verified by
-link:git-verify-tag.html[git-verify-tag].
+gitlink:git-verify-tag[1].
The "index" aka "Current Directory Cache"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You update the index with information from the working directory with
-the link:git-update-index.html[git-update-index] command. You
+the gitlink:git-update-index[1] command. You
generally update the index information by just specifying the filename
you want to update, like so:
You can examine the data represented in the object database and the
index with various helper tools. For every object, you can use
-link:git-cat-file.html[git-cat-file] to examine details about the
+gitlink:git-cat-file[1] to examine details about the
object:
git-cat-file -t <objectname>
--- /dev/null
+/*
+ * SHA-1 implementation optimized for ARM
+ *
+ * Copyright: (C) 2005 by Nicolas Pitre <nico@cam.org>
+ * Created: September 17, 2005
+ */
+
+#include <string.h>
+#include "sha1.h"
+
+extern void sha_transform(uint32_t *hash, const unsigned char *data, uint32_t *W);
+
+void SHA1_Init(SHA_CTX *c)
+{
+ c->len = 0;
+ c->hash[0] = 0x67452301;
+ c->hash[1] = 0xefcdab89;
+ c->hash[2] = 0x98badcfe;
+ c->hash[3] = 0x10325476;
+ c->hash[4] = 0xc3d2e1f0;
+}
+
+void SHA1_Update(SHA_CTX *c, const void *p, unsigned long n)
+{
+ uint32_t workspace[80];
+ unsigned int partial;
+ unsigned long done;
+
+ partial = c->len & 0x3f;
+ c->len += n;
+ if ((partial + n) >= 64) {
+ if (partial) {
+ done = 64 - partial;
+ memcpy(c->buffer + partial, p, done);
+ sha_transform(c->hash, c->buffer, workspace);
+ partial = 0;
+ } else
+ done = 0;
+ while (n >= done + 64) {
+ sha_transform(c->hash, p + done, workspace);
+ done += 64;
+ }
+ } else
+ done = 0;
+ if (n - done)
+ memcpy(c->buffer + partial, p + done, n - done);
+}
+
+void SHA1_Final(unsigned char *hash, SHA_CTX *c)
+{
+ uint64_t bitlen;
+ uint32_t bitlen_hi, bitlen_lo;
+ unsigned int i, offset, padlen;
+ unsigned char bits[8];
+ static const unsigned char padding[64] = { 0x80, };
+
+ bitlen = c->len << 3;
+ offset = c->len & 0x3f;
+ padlen = ((offset < 56) ? 56 : (64 + 56)) - offset;
+ SHA1_Update(c, padding, padlen);
+
+ bitlen_hi = bitlen >> 32;
+ bitlen_lo = bitlen & 0xffffffff;
+ bits[0] = bitlen_hi >> 24;
+ bits[1] = bitlen_hi >> 16;
+ bits[2] = bitlen_hi >> 8;
+ bits[3] = bitlen_hi;
+ bits[4] = bitlen_lo >> 24;
+ bits[5] = bitlen_lo >> 16;
+ bits[6] = bitlen_lo >> 8;
+ bits[7] = bitlen_lo;
+ SHA1_Update(c, bits, 8);
+
+ for (i = 0; i < 5; i++) {
+ uint32_t v = c->hash[i];
+ hash[0] = v >> 24;
+ hash[1] = v >> 16;
+ hash[2] = v >> 8;
+ hash[3] = v;
+ hash += 4;
+ }
+}
--- /dev/null
+/*
+ * SHA-1 implementation optimized for ARM
+ *
+ * Copyright: (C) 2005 by Nicolas Pitre <nico@cam.org>
+ * Created: September 17, 2005
+ */
+
+#include <stdint.h>
+
+typedef struct sha_context {
+ uint64_t len;
+ uint32_t hash[5];
+ unsigned char buffer[64];
+} SHA_CTX;
+
+void SHA1_Init(SHA_CTX *c);
+void SHA1_Update(SHA_CTX *c, const void *p, unsigned long n);
+void SHA1_Final(unsigned char *hash, SHA_CTX *c);
--- /dev/null
+/*
+ * SHA transform optimized for ARM
+ *
+ * Copyright: (C) 2005 by Nicolas Pitre <nico@cam.org>
+ * Created: September 17, 2005
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+ .text
+ .globl sha_transform
+
+/*
+ * void sha_transform(uint32_t *hash, const unsigned char *data, uint32_t *W);
+ *
+ * note: the "data" pointer may be unaligned.
+ */
+
+sha_transform:
+
+ stmfd sp!, {r4 - r8, lr}
+
+ @ for (i = 0; i < 16; i++)
+ @ W[i] = ntohl(((uint32_t *)data)[i]); */
+
+#ifdef __ARMEB__
+ mov r4, r0
+ mov r0, r2
+ mov r2, #64
+ bl memcpy
+ mov r2, r0
+ mov r0, r4
+#else
+ mov r3, r2
+ mov lr, #16
+1: ldrb r4, [r1], #1
+ ldrb r5, [r1], #1
+ ldrb r6, [r1], #1
+ ldrb r7, [r1], #1
+ subs lr, lr, #1
+ orr r5, r5, r4, lsl #8
+ orr r6, r6, r5, lsl #8
+ orr r7, r7, r6, lsl #8
+ str r7, [r3], #4
+ bne 1b
+#endif
+
+ @ for (i = 0; i < 64; i++)
+ @ W[i+16] = ror(W[i+13] ^ W[i+8] ^ W[i+2] ^ W[i], 31);
+
+ sub r3, r2, #4
+ mov lr, #64
+2: ldr r4, [r3, #4]!
+ subs lr, lr, #1
+ ldr r5, [r3, #8]
+ ldr r6, [r3, #32]
+ ldr r7, [r3, #52]
+ eor r4, r4, r5
+ eor r4, r4, r6
+ eor r4, r4, r7
+ mov r4, r4, ror #31
+ str r4, [r3, #64]
+ bne 2b
+
+ /*
+ * The SHA functions are:
+ *
+ * f1(B,C,D) = (D ^ (B & (C ^ D)))
+ * f2(B,C,D) = (B ^ C ^ D)
+ * f3(B,C,D) = ((B & C) | (D & (B | C)))
+ *
+ * Then the sub-blocks are processed as follows:
+ *
+ * A' = ror(A, 27) + f(B,C,D) + E + K + *W++
+ * B' = A
+ * C' = ror(B, 2)
+ * D' = C
+ * E' = D
+ *
+ * We therefore unroll each loop 5 times to avoid register shuffling.
+ * Also the ror for C (and also D and E which are successivelyderived
+ * from it) is applied in place to cut on an additional mov insn for
+ * each round.
+ */
+
+ .macro sha_f1, A, B, C, D, E
+ ldr r3, [r2], #4
+ eor ip, \C, \D
+ add \E, r1, \E, ror #2
+ and ip, \B, ip, ror #2
+ add \E, \E, \A, ror #27
+ eor ip, ip, \D, ror #2
+ add \E, \E, r3
+ add \E, \E, ip
+ .endm
+
+ .macro sha_f2, A, B, C, D, E
+ ldr r3, [r2], #4
+ add \E, r1, \E, ror #2
+ eor ip, \B, \C, ror #2
+ add \E, \E, \A, ror #27
+ eor ip, ip, \D, ror #2
+ add \E, \E, r3
+ add \E, \E, ip
+ .endm
+
+ .macro sha_f3, A, B, C, D, E
+ ldr r3, [r2], #4
+ add \E, r1, \E, ror #2
+ orr ip, \B, \C, ror #2
+ add \E, \E, \A, ror #27
+ and ip, ip, \D, ror #2
+ add \E, \E, r3
+ and r3, \B, \C, ror #2
+ orr ip, ip, r3
+ add \E, \E, ip
+ .endm
+
+ ldmia r0, {r4 - r8}
+
+ mov lr, #4
+ ldr r1, .L_sha_K + 0
+
+ /* adjust initial values */
+ mov r6, r6, ror #30
+ mov r7, r7, ror #30
+ mov r8, r8, ror #30
+
+3: subs lr, lr, #1
+ sha_f1 r4, r5, r6, r7, r8
+ sha_f1 r8, r4, r5, r6, r7
+ sha_f1 r7, r8, r4, r5, r6
+ sha_f1 r6, r7, r8, r4, r5
+ sha_f1 r5, r6, r7, r8, r4
+ bne 3b
+
+ ldr r1, .L_sha_K + 4
+ mov lr, #4
+
+4: subs lr, lr, #1
+ sha_f2 r4, r5, r6, r7, r8
+ sha_f2 r8, r4, r5, r6, r7
+ sha_f2 r7, r8, r4, r5, r6
+ sha_f2 r6, r7, r8, r4, r5
+ sha_f2 r5, r6, r7, r8, r4
+ bne 4b
+
+ ldr r1, .L_sha_K + 8
+ mov lr, #4
+
+5: subs lr, lr, #1
+ sha_f3 r4, r5, r6, r7, r8
+ sha_f3 r8, r4, r5, r6, r7
+ sha_f3 r7, r8, r4, r5, r6
+ sha_f3 r6, r7, r8, r4, r5
+ sha_f3 r5, r6, r7, r8, r4
+ bne 5b
+
+ ldr r1, .L_sha_K + 12
+ mov lr, #4
+
+6: subs lr, lr, #1
+ sha_f2 r4, r5, r6, r7, r8
+ sha_f2 r8, r4, r5, r6, r7
+ sha_f2 r7, r8, r4, r5, r6
+ sha_f2 r6, r7, r8, r4, r5
+ sha_f2 r5, r6, r7, r8, r4
+ bne 6b
+
+ ldmia r0, {r1, r2, r3, ip, lr}
+ add r4, r1, r4
+ add r5, r2, r5
+ add r6, r3, r6, ror #2
+ add r7, ip, r7, ror #2
+ add r8, lr, r8, ror #2
+ stmia r0, {r4 - r8}
+
+ ldmfd sp!, {r4 - r8, pc}
+
+.L_sha_K:
+ .word 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6
+
extern int remove_file_from_cache(char *path);
extern int ce_same_name(struct cache_entry *a, struct cache_entry *b);
extern int ce_match_stat(struct cache_entry *ce, struct stat *st);
+extern int ce_modified(struct cache_entry *ce, struct stat *st);
extern int ce_path_match(const struct cache_entry *ce, const char **pathspec);
extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, const char *type);
extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
unsigned char *sha1_ret);
const char *show_date(unsigned long time, int timezone);
-void parse_date(const char *date, char *buf, int bufsize);
+int parse_date(const char *date, char *buf, int bufsize);
void datestamp(char *buf, int bufsize);
extern int setup_ident(void);
#!/bin/sh
+#
+# This is for people who installed previous GIT by hand and would want
+# to remove the backward compatible links:
+#
+# ./cmd-rename.sh $bindir
+#
d="$1"
test -d "$d" || exit
while read old new
do
rm -f "$d/$old"
- if [ -x "$d/$new" ]; then
- ln -s "$new" "$d/$old"
- fi
done <<\EOF
git-add-script git-add
git-archimport-script git-archimport
#include <sys/time.h>
#include <netdb.h>
#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <syslog.h>
+
+static int log_syslog;
+static int verbose;
+
+static const char daemon_usage[] = "git-daemon [--verbose] [--syslog] [--inetd | --port=n]";
+
+
+static void logreport(int priority, const char *err, va_list params)
+{
+ /* We should do a single write so that it is atomic and output
+ * of several processes do not get intermingled. */
+ char buf[1024];
+ int buflen;
+ int maxlen, msglen;
+
+ /* sizeof(buf) should be big enough for "[pid] \n" */
+ buflen = snprintf(buf, sizeof(buf), "[%ld] ", (long) getpid());
+
+ maxlen = sizeof(buf) - buflen - 1; /* -1 for our own LF */
+ msglen = vsnprintf(buf + buflen, maxlen, err, params);
+
+ if (log_syslog) {
+ syslog(priority, "%s", buf);
+ return;
+ }
+
+ /* maxlen counted our own LF but also counts space given to
+ * vsnprintf for the terminating NUL. We want to make sure that
+ * we have space for our own LF and NUL after the "meat" of the
+ * message, so truncate it at maxlen - 1.
+ */
+ if (msglen > maxlen - 1)
+ msglen = maxlen - 1;
+ else if (msglen < 0)
+ msglen = 0; /* Protect against weird return values. */
+ buflen += msglen;
+
+ buf[buflen++] = '\n';
+ buf[buflen] = '\0';
+
+ write(2, buf, buflen);
+}
+
+void logerror(const char *err, ...)
+{
+ va_list params;
+ va_start(params, err);
+ logreport(LOG_ERR, err, params);
+ va_end(params);
+}
+
+void loginfo(const char *err, ...)
+{
+ va_list params;
+ if (!verbose)
+ return;
+ va_start(params, err);
+ logreport(LOG_INFO, err, params);
+ va_end(params);
+}
-static const char daemon_usage[] = "git-daemon [--inetd | --port=n]";
static int upload(char *dir, int dirlen)
{
- if (chdir(dir) < 0)
+ loginfo("Request for '%s'", dir);
+ if (chdir(dir) < 0) {
+ logerror("Cannot chdir('%s'): %s", dir, strerror(errno));
return -1;
+ }
chdir(".git");
/*
*/
if (access("git-daemon-export-ok", F_OK) ||
access("objects/00", X_OK) ||
- access("HEAD", R_OK))
+ access("HEAD", R_OK)) {
+ logerror("Not a valid gitd-enabled repository: '%s'", dir);
return -1;
+ }
/*
* We'll ignore SIGTERM from now on, we have a
if (!strncmp("git-upload-pack /", line, 17))
return upload(line + 16, len - 16);
- fprintf(stderr, "got bad connection '%s'\n", line);
+ logerror("Protocol error: '%s'", line);
return -1;
}
static void handle(int incoming, struct sockaddr *addr, int addrlen)
{
pid_t pid = fork();
+ char addrbuf[256] = "";
+ int port = -1;
if (pid) {
unsigned idx;
dup2(incoming, 0);
dup2(incoming, 1);
close(incoming);
+
+ if (addr->sa_family == AF_INET) {
+ struct sockaddr_in *sin_addr = (void *) addr;
+ inet_ntop(AF_INET, &sin_addr->sin_addr, addrbuf, sizeof(addrbuf));
+ port = sin_addr->sin_port;
+
+ } else if (addr->sa_family == AF_INET6) {
+ struct sockaddr_in6 *sin6_addr = (void *) addr;
+
+ char *buf = addrbuf;
+ *buf++ = '['; *buf = '\0'; /* stpcpy() is cool */
+ inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf, sizeof(addrbuf) - 1);
+ strcat(buf, "]");
+
+ port = sin6_addr->sin6_port;
+ }
+ loginfo("Connection from %s:%d", addrbuf, port);
+
exit(execute());
}
static void child_handler(int signo)
{
for (;;) {
- pid_t pid = waitpid(-1, NULL, WNOHANG);
+ int status;
+ pid_t pid = waitpid(-1, &status, WNOHANG);
if (pid > 0) {
unsigned reaped = children_reaped;
dead_child[reaped % MAX_CHILDREN] = pid;
children_reaped = reaped + 1;
+ /* XXX: Custom logging, since we don't wanna getpid() */
+ if (verbose) {
+ char *dead = "";
+ if (!WIFEXITED(status) || WEXITSTATUS(status) > 0)
+ dead = " (with error)";
+ if (log_syslog)
+ syslog(LOG_INFO, "[%d] Disconnected%s", pid, dead);
+ else
+ fprintf(stderr, "[%d] Disconnected%s\n", pid, dead);
+ }
continue;
}
break;
inetd_mode = 1;
continue;
}
+ if (!strcmp(arg, "--verbose")) {
+ verbose = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--syslog")) {
+ log_syslog = 1;
+ openlog("git-daemon", 0, LOG_DAEMON);
+ continue;
+ }
usage(daemon_usage);
}
return end - date;
}
+static int date_string(unsigned long date, int offset, char *buf, int len)
+{
+ int sign = '+';
+
+ if (offset < 0) {
+ offset = -offset;
+ sign = '-';
+ }
+ return snprintf(buf, len, "%lu %c%02d%02d", date, sign, offset / 60, offset % 60);
+}
+
/* Gr. strptime is crap for this; it doesn't have a way to require RFC2822
(i.e. English) day/month names, and it doesn't work correctly with %z. */
-void parse_date(const char *date, char *result, int maxlen)
+int parse_date(const char *date, char *result, int maxlen)
{
struct tm tm;
- int offset, sign, tm_gmt;
+ int offset, tm_gmt;
time_t then;
memset(&tm, 0, sizeof(tm));
offset = (then - mktime(&tm)) / 60;
if (then == -1)
- return;
+ return -1;
if (!tm_gmt)
then -= offset * 60;
-
- sign = '+';
- if (offset < 0) {
- offset = -offset;
- sign = '-';
- }
-
- snprintf(result, maxlen, "%lu %c%02d%02d", then, sign, offset/60, offset % 60);
+ return date_string(then, offset, result, maxlen);
}
void datestamp(char *buf, int bufsize)
offset = my_mktime(localtime(&now)) - now;
offset /= 60;
- snprintf(buf, bufsize, "%lu %+05d", now, offset/60*100 + offset%60);
+ date_string(now, offset, buf, bufsize);
}
+++ /dev/null
-/*
- * Copyright (C) 2005 Junio C Hamano
- */
-#include "cache.h"
-#include "strbuf.h"
-#include "diff.h"
-
-static const char *pickaxe = NULL;
-static int pickaxe_opts = 0;
-static const char *orderfile = NULL;
-static const char *diff_filter = NULL;
-static int line_termination = '\n';
-static int inter_name_termination = '\t';
-
-static void flush_them(int ac, const char **av)
-{
- diffcore_std_no_resolve(av + 1,
- pickaxe, pickaxe_opts,
- orderfile, diff_filter);
- diff_flush(DIFF_FORMAT_PATCH, '\n');
-}
-
-static const char diff_helper_usage[] =
-"git-diff-helper [-z] [-O<orderfile>] [-S<string>] [--pickaxe-all] [<path>...]";
-
-int main(int ac, const char **av) {
- struct strbuf sb;
- const char *garbage_flush_format;
-
- strbuf_init(&sb);
-
- while (1 < ac && av[1][0] == '-') {
- if (av[1][1] == 'z')
- line_termination = inter_name_termination = 0;
- else if (av[1][1] == 'S') {
- pickaxe = av[1] + 2;
- }
- else if (!strcmp(av[1], "--pickaxe-all"))
- pickaxe_opts = DIFF_PICKAXE_ALL;
- else if (!strncmp(av[1], "--diff-filter=", 14))
- diff_filter = av[1] + 14;
- else if (!strncmp(av[1], "-O", 2))
- orderfile = av[1] + 2;
- else
- usage(diff_helper_usage);
- ac--; av++;
- }
- garbage_flush_format = (line_termination == 0) ? "%s" : "%s\n";
-
- /* the remaining parameters are paths patterns */
-
- diff_setup(0);
- while (1) {
- unsigned old_mode, new_mode;
- unsigned char old_sha1[20], new_sha1[20];
- char old_path[PATH_MAX];
- int status, score, two_paths;
- char new_path[PATH_MAX];
-
- int ch;
- char *cp, *ep;
-
- read_line(&sb, stdin, line_termination);
- if (sb.eof)
- break;
- switch (sb.buf[0]) {
- case ':':
- /* parse the first part up to the status */
- cp = sb.buf + 1;
- old_mode = new_mode = 0;
- while ((ch = *cp) && ('0' <= ch && ch <= '7')) {
- old_mode = (old_mode << 3) | (ch - '0');
- cp++;
- }
- if (*cp++ != ' ')
- break;
- while ((ch = *cp) && ('0' <= ch && ch <= '7')) {
- new_mode = (new_mode << 3) | (ch - '0');
- cp++;
- }
- if (*cp++ != ' ')
- break;
- if (get_sha1_hex(cp, old_sha1))
- break;
- cp += 40;
- if (*cp++ != ' ')
- break;
- if (get_sha1_hex(cp, new_sha1))
- break;
- cp += 40;
- if (*cp++ != ' ')
- break;
- status = *cp++;
- if (!strchr("AMCRDU", status))
- break;
- two_paths = score = 0;
- if (status == DIFF_STATUS_RENAMED ||
- status == DIFF_STATUS_COPIED)
- two_paths = 1;
-
- /* pick up score if exists */
- if (sscanf(cp, "%d", &score) != 1)
- score = 0;
- cp = strchr(cp,
- inter_name_termination);
- if (!cp)
- break;
- if (*cp++ != inter_name_termination)
- break;
-
- /* first pathname */
- if (!line_termination) {
- read_line(&sb, stdin, line_termination);
- if (sb.eof)
- break;
- strcpy(old_path, sb.buf);
- }
- else if (!two_paths)
- strcpy(old_path, cp);
- else {
- ep = strchr(cp, inter_name_termination);
- if (!ep)
- break;
- strncpy(old_path, cp, ep-cp);
- old_path[ep-cp] = 0;
- cp = ep + 1;
- }
-
- /* second pathname */
- if (!two_paths)
- strcpy(new_path, old_path);
- else {
- if (!line_termination) {
- read_line(&sb, stdin,
- line_termination);
- if (sb.eof)
- break;
- strcpy(new_path, sb.buf);
- }
- else
- strcpy(new_path, cp);
- }
- diff_helper_input(old_mode, new_mode,
- old_sha1, new_sha1,
- old_path, status, score,
- new_path);
- continue;
- }
- flush_them(ac, av);
- printf(garbage_flush_format, sb.buf);
- }
- flush_them(ac, av);
- return 0;
-}
diff_queue(&diff_queued_diff, one, two);
}
-void diff_helper_input(unsigned old_mode,
- unsigned new_mode,
- const unsigned char *old_sha1,
- const unsigned char *new_sha1,
- const char *old_path,
- int status,
- int score,
- const char *new_path)
-{
- struct diff_filespec *one, *two;
- struct diff_filepair *dp;
-
- one = alloc_filespec(old_path);
- two = alloc_filespec(new_path);
- if (old_mode)
- fill_filespec(one, old_sha1, old_mode);
- if (new_mode)
- fill_filespec(two, new_sha1, new_mode);
- dp = diff_queue(&diff_queued_diff, one, two);
- dp->score = score * MAX_SCORE / 100;
- dp->status = status;
-}
-
void diff_change(unsigned old_mode, unsigned new_mode,
const unsigned char *old_sha1,
const unsigned char *new_sha1,
const unsigned char *sha2,
const char *base, const char *path);
-extern void diff_helper_input(unsigned mode1,
- unsigned mode2,
- const unsigned char *sha1,
- const unsigned char *sha2,
- const char *path1,
- int status,
- int score,
- const char *path2);
-
extern void diff_unmerge(const char *path);
extern int diff_scoreopt_parse(const char *opt);
+++ /dev/null
-#include "cache.h"
-#include "commit.h"
-
-/*
- * Show one commit
- */
-static void show_commit(struct commit *commit)
-{
- char cmdline[400];
- char hex[100];
-
- strcpy(hex, sha1_to_hex(commit->object.sha1));
- printf("Id: %s\n", hex);
- fflush(NULL);
- sprintf(cmdline, "git-cat-file commit %s", hex);
- system(cmdline);
- if (commit->parents) {
- char *against = sha1_to_hex(commit->parents->item->object.sha1);
- printf("\n\n======== diff against %s ========\n", against);
- fflush(NULL);
- sprintf(cmdline, "git-diff-tree -p %s %s", against, hex);
- system(cmdline);
- }
- printf("======== end ========\n\n");
-}
-
-/*
- * Show all unseen commits, depth-first
- */
-static void show_unseen(struct commit *top)
-{
- struct commit_list *parents;
-
- if (top->object.flags & 2)
- return;
- top->object.flags |= 2;
- parents = top->parents;
- while (parents) {
- show_unseen(parents->item);
- parents = parents->next;
- }
- show_commit(top);
-}
-
-static void export(struct commit *top, struct commit *base)
-{
- mark_reachable(&top->object, 1);
- if (base)
- mark_reachable(&base->object, 2);
- show_unseen(top);
-}
-
-static struct commit *get_commit(unsigned char *sha1)
-{
- struct commit *commit = lookup_commit(sha1);
- if (!commit->object.parsed) {
- struct commit_list *parents;
-
- if (parse_commit(commit) < 0)
- die("unable to parse commit %s", sha1_to_hex(sha1));
- parents = commit->parents;
- while (parents) {
- get_commit(parents->item->object.sha1);
- parents = parents->next;
- }
- }
- return commit;
-}
-
-int main(int argc, char **argv)
-{
- unsigned char base_sha1[20];
- unsigned char top_sha1[20];
-
- if (argc < 2 || argc > 4 ||
- get_sha1(argv[1], top_sha1) ||
- (argc == 3 && get_sha1(argv[2], base_sha1)))
- usage("git-export top [base]");
- export(get_commit(top_sha1), argc==3 ? get_commit(base_sha1) : NULL);
- return 0;
-}
static int keep_cache_objects = 0;
static unsigned char head_sha1[20];
+
+static void objreport(struct object *obj, const char *severity,
+ const char *err, va_list params)
+{
+ fprintf(stderr, "%s in %s %s: ",
+ severity, obj->type, sha1_to_hex(obj->sha1));
+ vfprintf(stderr, err, params);
+ fputs("\n", stderr);
+}
+
+int objerror(struct object *obj, const char *err, ...)
+{
+ va_list params;
+ va_start(params, err);
+ objreport(obj, "error", err, params);
+ va_end(params);
+ return -1;
+}
+
+int objwarning(struct object *obj, const char *err, ...)
+{
+ va_list params;
+ va_start(params, err);
+ objreport(obj, "warning", err, params);
+ va_end(params);
+ return -1;
+}
+
+
static void check_connectivity(void)
{
int i;
retval = 0;
if (has_full_path) {
- fprintf(stderr, "warning: git-fsck-objects: tree %s "
- "has full pathnames in it\n",
- sha1_to_hex(item->object.sha1));
+ objwarning(&item->object, "contains full pathnames");
}
if (has_zero_pad) {
- fprintf(stderr, "warning: git-fsck-objects: tree %s "
- "has zero-padded file modes in it\n",
- sha1_to_hex(item->object.sha1));
+ objwarning(&item->object, "contains zero-padded file modes");
}
if (has_bad_modes) {
- fprintf(stderr, "warning: git-fsck-objects: tree %s "
- "has bad file modes in it\n",
- sha1_to_hex(item->object.sha1));
+ objwarning(&item->object, "contains bad file modes");
}
if (has_dup_entries) {
- fprintf(stderr, "error: git-fsck-objects: tree %s "
- "has duplicate file entries\n",
- sha1_to_hex(item->object.sha1));
- retval = -1;
+ retval = objerror(&item->object, "contains duplicate file entries");
}
if (not_properly_sorted) {
- fprintf(stderr, "error: git-fsck-objects: tree %s "
- "is not properly sorted\n",
- sha1_to_hex(item->object.sha1));
- retval = -1;
+ retval = objerror(&item->object, "not properly sorted");
}
return retval;
}
static int fsck_commit(struct commit *commit)
{
char *buffer = commit->buffer;
- unsigned char sha1[20];
+ unsigned char tree_sha1[20], sha1[20];
if (memcmp(buffer, "tree ", 5))
- return -1;
- if (get_sha1_hex(buffer+5, sha1) || buffer[45] != '\n')
- return -1;
+ return objerror(&commit->object, "invalid format - expected 'tree' line");
+ if (get_sha1_hex(buffer+5, tree_sha1) || buffer[45] != '\n')
+ return objerror(&commit->object, "invalid 'tree' line format - bad sha1");
buffer += 46;
while (!memcmp(buffer, "parent ", 7)) {
if (get_sha1_hex(buffer+7, sha1) || buffer[47] != '\n')
- return -1;
+ return objerror(&commit->object, "invalid 'parent' line format - bad sha1");
buffer += 48;
}
if (memcmp(buffer, "author ", 7))
- return -1;
+ return objerror(&commit->object, "invalid format - expected 'author' line");
free(commit->buffer);
commit->buffer = NULL;
if (!commit->tree)
- return -1;
+ return objerror(&commit->object, "could not load commit's tree %s", tree_sha1);
if (!commit->parents && show_root)
printf("root %s\n", sha1_to_hex(commit->object.sha1));
if (!commit->date)
struct object *tagged = tag->tagged;
if (!tagged) {
- printf("bad object in tag %s\n", sha1_to_hex(tag->object.sha1));
- return -1;
+ return objerror(&tag->object, "could not load tagged object");
}
if (!show_tags)
return 0;
{
struct object *obj = parse_object(sha1);
if (!obj)
- return -1;
+ return error("%s: object not found", sha1_to_hex(sha1));
if (obj->type == blob_type)
return 0;
if (obj->type == tree_type)
return fsck_commit((struct commit *) obj);
if (obj->type == tag_type)
return fsck_tag((struct tag *) obj);
- return -1;
+ /* By now, parse_object() would've returned NULL instead. */
+ return objerror(obj, "unknown type '%s' (internal fsck error)", obj->type);
}
/*
unsigned char *sha1 = entry->sha1;
sha1_list.entry[i] = NULL;
- if (fsck_sha1(sha1) < 0)
- fprintf(stderr, "bad sha1 entry '%s'\n", sha1_to_hex(sha1));
+ fsck_sha1(sha1);
free(entry);
}
sha1_list.nr = 0;
for (i = 0; i < num; i++) {
unsigned char sha1[20];
nth_packed_object_sha1(p, i, sha1);
- if (fsck_sha1(sha1) < 0)
- fprintf(stderr, "bad sha1 entry '%s'\n", sha1_to_hex(sha1));
-
+ fsck_sha1(sha1);
}
}
}
heads++;
continue;
}
- error("expected sha1, got %s", arg);
+ error("invalid parameter: expected sha1, got '%s'", arg);
}
/*
then
HEAD=HEAD
fi
- tar Ccf "$repo" - refs $HEAD | tar Cxf "$D/.git" - || exit 1
+ (cd "$repo" && tar cf - refs $HEAD) |
+ (cd "$D/.git" && tar xf -) || exit 1
;;
*)
case "$repo" in
--- /dev/null
+#!/usr/bin/perl -w
+#
+# Copyright (c) 2005 Junio C Hamano
+#
+# Read .git/FETCH_HEAD and make a human readable merge message
+# by grouping branches and tags together to form a single line.
+
+use strict;
+
+my @src;
+my %src;
+sub andjoin {
+ my ($label, $labels, $stuff) = @_;
+ my $l = scalar @$stuff;
+ my $m = '';
+ if ($l == 0) {
+ return ();
+ }
+ if ($l == 1) {
+ $m = "$label$stuff->[0]";
+ }
+ else {
+ $m = ("$labels" .
+ join (', ', @{$stuff}[0..$l-2]) .
+ " and $stuff->[-1]");
+ }
+ return ($m);
+}
+
+while (<>) {
+ my ($bname, $tname, $gname, $src);
+ chomp;
+ s/^[0-9a-f]* //;
+ if (s/ of (.*)$//) {
+ $src = $1;
+ } else {
+ # Pulling HEAD
+ $src = $_;
+ $_ = 'HEAD';
+ }
+ if (! exists $src{$src}) {
+ push @src, $src;
+ $src{$src} = {
+ BRANCH => [],
+ TAG => [],
+ GENERIC => [],
+ # &1 == has HEAD.
+ # &2 == has others.
+ HEAD_STATUS => 0,
+ };
+ }
+ if (/^branch (.*)$/) {
+ push @{$src{$src}{BRANCH}}, $1;
+ $src{$src}{HEAD_STATUS} |= 2;
+ }
+ elsif (/^tag (.*)$/) {
+ push @{$src{$src}{TAG}}, $1;
+ $src{$src}{HEAD_STATUS} |= 2;
+ }
+ elsif (/^HEAD$/) {
+ $src{$src}{HEAD_STATUS} |= 1;
+ }
+ else {
+ push @{$src{$src}{GENERIC}}, $_;
+ $src{$src}{HEAD_STATUS} |= 2;
+ }
+}
+
+my @msg;
+for my $src (@src) {
+ if ($src{$src}{HEAD_STATUS} == 1) {
+ # Only HEAD is fetched, nothing else.
+ push @msg, $src;
+ next;
+ }
+ my @this;
+ if ($src{$src}{HEAD_STATUS} == 3) {
+ # HEAD is fetched among others.
+ push @this, andjoin('', '', ['HEAD']);
+ }
+ push @this, andjoin("branch ", "branches ",
+ $src{$src}{BRANCH});
+ push @this, andjoin("tag ", "tags ",
+ $src{$src}{TAG});
+ push @this, andjoin("commit ", "commits ",
+ $src{$src}{GENERIC});
+ my $this = join(', ', @this);
+ if ($src ne '.') {
+ $this .= " from $src";
+ }
+ push @msg, $this;
+}
+print "Merge ", join("; ", @msg), "\n";
# MRC is the current "merge reference commit"
# MRT is the current "merge result tree"
-MRC=$head MSG= PARENT="-p $head"
+MRC=$head PARENT="-p $head"
MRT=$(git-write-tree)
CNT=1 ;# counting our head
NON_FF_MERGE=0
CNT=`expr $CNT + 1`
PARENT="$PARENT -p $SHA1"
- MSG="$MSG
- $REPO"
if test "$common,$NON_FF_MERGE" = "$MRC,0"
then
1)
echo "No changes."
exit 0 ;;
-2)
- echo "Not an Octopus; making an ordinary commit."
- MSG="Merge "`expr "$MSG" : '. \(.*\)'` ; # remove LF and TAB
- ;;
-*)
- # In an octopus, the original head is just one of the equals,
- # so we should list it as such.
- HEAD_LINK=`readlink "$GIT_DIR/HEAD"`
- MSG="Octopus merge of the following:
-
- $HEAD_LINK from .$MSG"
- ;;
esac
-result_commit=$(echo "$MSG" | git-commit-tree $MRT $PARENT)
+result_commit=$(git-fmt-merge-msg <"$GIT_DIR/FETCH_HEAD" |
+ git-commit-tree $MRT $PARENT)
echo "Committed merge $result_commit"
echo $result_commit >"$GIT_DIR"/HEAD
git-diff-tree -p $head $result_commit | git-apply --stat
fi
merge_head=$(sed -e 's/ .*//' "$GIT_DIR"/FETCH_HEAD | tr '\012' ' ')
-merge_name=$(
- perl -e 'print join("; ", map { chomp; s/^[0-9a-f]* //; $_ } <>)' \
- "$GIT_DIR"/FETCH_HEAD
-)
case "$merge_head" in
'')
;;
esac
-git-resolve \
- "$(cat "$GIT_DIR"/HEAD)" \
- $merge_head "Merge $merge_name"
+merge_name=$(git-fmt-merge-msg <"$GIT_DIR/FETCH_HEAD")
+git-resolve "$(cat "$GIT_DIR"/HEAD)" $merge_head "$merge_name"
while (<$fh>) {
chomp;
if (! exists $keep{$_}) {
- print "$_\0";
+ # it is ok if this fails -- it may already
+ # have been culled by checkout-index.
+ unlink $_;
}
}
- ' $tmp-exists | xargs -0 rm -f --
+ ' $tmp-exists
;;
--soft )
;; # Nothing else to do
static char real_name[1000];
static char real_date[50];
+static void copy_gecos(struct passwd *w, char *name, int sz)
+{
+ char *src, *dst;
+ int len, nlen;
+
+ nlen = strlen(w->pw_name);
+
+ /* Traditionally GECOS field had office phone numbers etc, separated
+ * with commas. Also & stands for capitalized form of the login name.
+ */
+
+ for (len = 0, dst = name, src = w->pw_gecos; len < sz; src++) {
+ int ch = *src;
+ if (ch != '&') {
+ *dst++ = ch;
+ if (ch == 0 || ch == ',')
+ break;
+ len++;
+ continue;
+ }
+ if (len + nlen < sz) {
+ /* Sorry, Mr. McDonald... */
+ *dst++ = toupper(*w->pw_name);
+ memcpy(dst, w->pw_name + 1, nlen - 1);
+ dst += nlen - 1;
+ }
+ }
+ if (len < sz)
+ name[len] = 0;
+ else
+ die("Your parents must have hated you!");
+
+}
+
int setup_ident(void)
{
int len;
die("You don't exist. Go away!");
/* Get the name ("gecos") */
- len = strlen(pw->pw_gecos);
- if (len >= sizeof(real_name))
- die("Your parents must have hated you!");
- memcpy(real_name, pw->pw_gecos, len+1);
+ copy_gecos(pw, real_name, sizeof(real_name));
/* Make up a fake email address (name + '@' + hostname [+ '.' + domainname]) */
len = strlen(pw->pw_name);
static int show_ignored = 0;
static int show_stage = 0;
static int show_unmerged = 0;
+static int show_modified = 0;
static int show_killed = 0;
static int line_terminator = '\n';
static const char *tag_removed = "";
static const char *tag_other = "";
static const char *tag_killed = "";
+static const char *tag_modified = "";
static char *exclude_per_dir = NULL;
show_ce_entry(ce_stage(ce) ? tag_unmerged : tag_cached, ce);
}
}
- if (show_deleted) {
+ if (show_deleted | show_modified) {
for (i = 0; i < active_nr; i++) {
struct cache_entry *ce = active_cache[i];
struct stat st;
+ int err;
if (excluded(ce->name) != show_ignored)
continue;
- if (!lstat(ce->name, &st))
- continue;
- show_ce_entry(tag_removed, ce);
+ err = lstat(ce->name, &st);
+ if (show_deleted && err)
+ show_ce_entry(tag_removed, ce);
+ if (show_modified && ce_modified(ce, &st))
+ show_ce_entry(tag_modified, ce);
}
}
}
}
static const char ls_files_usage[] =
- "git-ls-files [-z] [-t] (--[cached|deleted|others|stage|unmerged|killed])* "
+ "git-ls-files [-z] [-t] (--[cached|deleted|others|stage|unmerged|killed|modified])* "
"[ --ignored ] [--exclude=<pattern>] [--exclude-from=<file>] "
"[ --exclude-per-directory=<filename> ]";
tag_cached = "H ";
tag_unmerged = "M ";
tag_removed = "R ";
+ tag_modified = "C ";
tag_other = "? ";
tag_killed = "K ";
continue;
show_deleted = 1;
continue;
}
+ if (!strcmp(arg, "-m") || !strcmp(arg, "--modified")) {
+ show_modified = 1;
+ continue;
+ }
if (!strcmp(arg, "-o") || !strcmp(arg, "--others")) {
show_others = 1;
continue;
}
/* With no flags, we default to showing the cached files */
- if (!(show_stage | show_deleted | show_others | show_unmerged | show_killed))
+ if (!(show_stage | show_deleted | show_others | show_unmerged |
+ show_killed | show_modified))
show_cached = 1;
read_cache();
return changed;
}
+static int ce_compare_data(struct cache_entry *ce, struct stat *st)
+{
+ int match = -1;
+ int fd = open(ce->name, O_RDONLY);
+
+ if (fd >= 0) {
+ unsigned char sha1[20];
+ if (!index_fd(sha1, fd, st, 0, NULL))
+ match = memcmp(sha1, ce->sha1, 20);
+ close(fd);
+ }
+ return match;
+}
+
+static int ce_compare_link(struct cache_entry *ce, unsigned long expected_size)
+{
+ int match = -1;
+ char *target;
+ void *buffer;
+ unsigned long size;
+ char type[10];
+ int len;
+
+ target = xmalloc(expected_size);
+ len = readlink(ce->name, target, expected_size);
+ if (len != expected_size) {
+ free(target);
+ return -1;
+ }
+ buffer = read_sha1_file(ce->sha1, type, &size);
+ if (!buffer) {
+ free(target);
+ return -1;
+ }
+ if (size == expected_size)
+ match = memcmp(buffer, target, size);
+ free(buffer);
+ free(target);
+ return match;
+}
+
+int ce_modified(struct cache_entry *ce, struct stat *st)
+{
+ int changed;
+ changed = ce_match_stat(ce, st);
+ if (!changed)
+ return 0;
+
+ /*
+ * If the mode or type has changed, there's no point in trying
+ * to refresh the entry - it's not going to match
+ */
+ if (changed & (MODE_CHANGED | TYPE_CHANGED))
+ return changed;
+
+ /* Immediately after read-tree or update-index --cacheinfo,
+ * the length field is zero. For other cases the ce_size
+ * should match the SHA1 recorded in the index entry.
+ */
+ if ((changed & DATA_CHANGED) && ce->ce_size != htonl(0))
+ return changed;
+
+ switch (st->st_mode & S_IFMT) {
+ case S_IFREG:
+ if (ce_compare_data(ce, st))
+ return changed | DATA_CHANGED;
+ break;
+ case S_IFLNK:
+ if (ce_compare_link(ce, st->st_size))
+ return changed | DATA_CHANGED;
+ break;
+ default:
+ return changed | TYPE_CHANGED;
+ }
+ return 0;
+}
+
int base_name_compare(const char *name1, int len1, int mode1,
const char *name2, int len2, int mode2)
{
die("failed to unpack tree object %s", arg);
stage++;
}
- if (update && !merge)
+ if ((update||index_only) && !merge)
usage(read_tree_usage);
if (merge && !fn) {
if (stage < 2)
return CONTINUE;
if (max_age != -1 && (commit->date < max_age)) {
stop_traversal=1;
- return merge_order?CONTINUE:STOP;
+ return CONTINUE;
}
if (max_count != -1 && !max_count--)
return STOP;
struct commit *commit = pop_most_recent_commit(&list, SEEN);
struct object *obj = &commit->object;
+ if (max_age != -1 && (commit->date < max_age))
+ obj->flags |= UNINTERESTING;
if (unpacked && has_sha1_pack(obj->sha1))
obj->flags |= UNINTERESTING;
if (obj->flags & UNINTERESTING) {
break;
continue;
}
+ if (min_age != -1 && (commit->date > min_age))
+ continue;
p = &commit_list_insert(commit, p)->next;
}
if (tree_objects)
}
if (!strncmp(arg, "--max-age=", 10)) {
max_age = atoi(arg + 10);
+ limited = 1;
continue;
}
if (!strncmp(arg, "--min-age=", 10)) {
min_age = atoi(arg + 10);
+ limited = 1;
continue;
}
if (!strcmp(arg, "--header")) {
#include "cache.h"
#include "commit.h"
#include "refs.h"
+#include "quote.h"
#define DO_REVS 1
#define DO_NOREV 2
return 0;
}
+static void show_datestring(const char *flag, const char *datestr)
+{
+ FILE *date;
+ static char buffer[100];
+ static char cmd[1000];
+ int len;
+
+ /* date handling requires both flags and revs */
+ if ((filter & (DO_FLAGS | DO_REVS)) != (DO_FLAGS | DO_REVS))
+ return;
+ len = strlen(flag);
+ memcpy(buffer, flag, len);
+
+ snprintf(cmd, sizeof(cmd), "date --date=%s +%%s", sq_quote(datestr));
+ date = popen(cmd, "r");
+ if (!date || !fgets(buffer + len, sizeof(buffer) - len, date))
+ die("git-rev-list: bad date string");
+ pclose(date);
+ len = strlen(buffer);
+ if (buffer[len-1] == '\n')
+ buffer[--len] = 0;
+ show(buffer);
+}
+
int main(int argc, char **argv)
{
int i, as_is = 0, verify = 0;
printf("%s/.git\n", cwd);
continue;
}
+ if (!strncmp(arg, "--since=", 8)) {
+ show_datestring("--max-age=", arg+8);
+ continue;
+ }
+ if (!strncmp(arg, "--after=", 8)) {
+ show_datestring("--max-age=", arg+8);
+ continue;
+ }
+ if (!strncmp(arg, "--before=", 9)) {
+ show_datestring("--min-age=", arg+9);
+ continue;
+ }
+ if (!strncmp(arg, "--until=", 8)) {
+ show_datestring("--min-age=", arg+8);
+ continue;
+ }
if (verify)
die("Needed a single revision");
show_flag(arg);
+++ /dev/null
-#include "cache.h"
-#include "commit.h"
-
-/*
- * revision.h leaves the low 16 bits of the "flags" field of the
- * revision data structure unused. We use it for a "reachable from
- * this commit <N>" bitmask.
- */
-#define MAX_COMMITS 16
-#define REACHABLE (1U << 16)
-
-#define cmit_flags(cmit) ((cmit)->object.flags & ~REACHABLE)
-
-static int show_edges = 0;
-static int basemask = 0;
-
-static void read_cache_file(const char *path)
-{
- die("no revtree cache file yet");
-}
-
-/*
- * Some revisions are less interesting than others.
- *
- * For example, if we use a cache-file, that one may contain
- * revisions that were never used. They are never interesting.
- *
- * And sometimes we're only interested in "edge" commits, ie
- * places where the marking changes between parent and child.
- */
-static int interesting(struct commit *rev)
-{
- unsigned mask = cmit_flags(rev);
-
- if (!mask)
- return 0;
- if (show_edges) {
- struct commit_list *p = rev->parents;
- while (p) {
- if (mask != cmit_flags(p->item))
- return 1;
- p = p->next;
- }
- return 0;
- }
- if (mask & basemask)
- return 0;
-
- return 1;
-}
-
-/*
- * Usage: git-rev-tree [--edges] [--cache <cache-file>] <commit-id> [<commit-id2>]
- *
- * The cache-file can be quite important for big trees. This is an
- * expensive operation if you have to walk the whole chain of
- * parents in a tree with a long revision history.
- */
-int main(int argc, char **argv)
-{
- int i;
- int nr = 0;
- unsigned char sha1[MAX_COMMITS][20];
- struct commit_list *list = NULL;
-
- /*
- * First - pick up all the revisions we can (both from
- * caches and from commit file chains).
- */
- for (i = 1; i < argc ; i++) {
- char *arg = argv[i];
- struct commit *commit;
-
- if (!strcmp(arg, "--cache")) {
- read_cache_file(argv[++i]);
- continue;
- }
-
- if (!strcmp(arg, "--edges")) {
- show_edges = 1;
- continue;
- }
-
- if (arg[0] == '^') {
- arg++;
- basemask |= 1<<nr;
- }
- if (nr >= MAX_COMMITS || get_sha1(arg, sha1[nr]))
- usage("git-rev-tree [--edges] [--cache <cache-file>] <commit-id> [<commit-id>]");
-
- commit = lookup_commit_reference(sha1[nr]);
- if (!commit || parse_commit(commit) < 0)
- die("bad commit object");
- commit_list_insert(commit, &list);
- nr++;
- }
-
- /*
- * Parse all the commits in date order.
- *
- * We really should stop once we know enough, but that's a
- * decision that isn't trivial to make.
- */
- while (list)
- pop_most_recent_commit(&list, REACHABLE);
-
- /*
- * Now we have the maximal tree. Walk the different sha files back to the root.
- */
- for (i = 0; i < nr; i++)
- mark_reachable(&lookup_commit_reference(sha1[i])->object, 1 << i);
-
- /*
- * Now print out the results..
- */
- for (i = 0; i < nr_objs; i++) {
- struct object *obj = objs[i];
- struct commit *commit;
- struct commit_list *p;
-
- if (obj->type != commit_type)
- continue;
-
- commit = (struct commit *) obj;
-
- if (!interesting(commit))
- continue;
-
- printf("%lu %s:%d", commit->date, sha1_to_hex(obj->sha1),
- cmit_flags(commit));
- p = commit->parents;
- while (p) {
- printf(" %s:%d", sha1_to_hex(p->item->object.sha1),
- cmit_flags(p->item));
- p = p->next;
- }
- printf("\n");
- }
- return 0;
-}
--- /dev/null
+#!/bin/sh
+#
+# Copyright (c) 2005 Junio C Hamano
+#
+
+test_description='git-ls-files -k and -m flags test.
+
+This test prepares the following in the cache:
+
+ path0 - a file
+ path1 - a symlink
+ path2/file2 - a file in a directory
+ path3/file3 - a file in a directory
+
+and the following on the filesystem:
+
+ path0/file0 - a file in a directory
+ path1/file1 - a file in a directory
+ path2 - a file
+ path3 - a symlink
+ path4 - a file
+ path5 - a symlink
+ path6/file6 - a file in a directory
+
+git-ls-files -k should report that existing filesystem
+objects except path4, path5 and path6/file6 to be killed.
+
+Also for modification test, the cache and working tree have:
+
+ path7 - an empty file, modified to a non-empty file.
+ path8 - a non-empty file, modified to an empty file.
+ path9 - an empty file, cache dirtied.
+ path10 - a non-empty file, cache dirtied.
+
+We should report path0, path1, path2/file2, path3/file3, path7 and path8
+modified without reporting path9 and path10.
+'
+. ./test-lib.sh
+
+date >path0
+ln -s xyzzy path1
+mkdir path2 path3
+date >path2/file2
+date >path3/file3
+: >path7
+date >path8
+: >path9
+date >path10
+test_expect_success \
+ 'git-update-index --add to add various paths.' \
+ "git-update-index --add -- path0 path1 path?/file? path7 path8 path9 path10"
+
+rm -fr path? ;# leave path10 alone
+date >path2
+ln -s frotz path3
+ln -s nitfol path5
+mkdir path0 path1 path6
+date >path0/file0
+date >path1/file1
+date >path6/file6
+date >path7
+: >path8
+: >path9
+touch path10
+
+test_expect_success \
+ 'git-ls-files -k to show killed files.' \
+ 'git-ls-files -k >.output'
+cat >.expected <<EOF
+path0/file0
+path1/file1
+path2
+path3
+EOF
+
+test_expect_success \
+ 'validate git-ls-files -k output.' \
+ 'diff .output .expected'
+
+test_expect_success \
+ 'git-ls-files -m to show modified files.' \
+ 'git-ls-files -m >.output'
+cat >.expected <<EOF
+path0
+path1
+path2/file2
+path3/file3
+path7
+path8
+EOF
+
+test_expect_success \
+ 'validate git-ls-files -m output.' \
+ 'diff .output .expected'
+
+test_done
+++ /dev/null
-#!/bin/sh
-#
-# Copyright (c) 2005 Junio C Hamano
-#
-
-test_description='git-ls-files -k flag test.
-
-This test prepares the following in the cache:
-
- path0 - a file
- path1 - a symlink
- path2/file2 - a file in a directory
- path3/file3 - a file in a directory
-
-and the following on the filesystem:
-
- path0/file0 - a file in a directory
- path1/file1 - a file in a directory
- path2 - a file
- path3 - a symlink
- path4 - a file
- path5 - a symlink
- path6/file6 - a file in a directory
-
-git-ls-files -k should report that existing filesystem
-objects except path4, path5 and path6/file6 to be killed.
-'
-. ./test-lib.sh
-
-date >path0
-ln -s xyzzy path1
-mkdir path2 path3
-date >path2/file2
-date >path3/file3
-test_expect_success \
- 'git-update-index --add to add various paths.' \
- "git-update-index --add -- path0 path1 path?/file?"
-
-rm -fr path?
-date >path2
-ln -s frotz path3
-ln -s nitfol path5
-mkdir path0 path1 path6
-date >path0/file0
-date >path1/file1
-date >path6/file6
-
-test_expect_success \
- 'git-ls-files -k to show killed files.' \
- 'git-ls-files -k >.output'
-cat >.expected <<EOF
-path0/file0
-path1/file1
-path2
-path3
-EOF
-
-test_expect_success \
- 'validate git-ls-files -k output.' \
- 'diff .output .expected'
-test_done
'validate git-diff-files -p output.' \
'cmp -s current expected'
-test_expect_success \
- 'build same diff using git-diff-helper.' \
- 'git-diff-files -z | git-diff-helper -z >current'
-
-
-test_expect_success \
- 'validate git-diff-helper output.' \
- 'cmp -s current expected'
-
test_done
'validate output from rename/copy detection (#1)' \
'compare_diff_raw current expected'
-# make sure diff-helper can grok it.
-mv expected diff-raw
-GIT_DIFF_OPTS=--unified=0 git-diff-helper <diff-raw >current
-cat >expected <<\EOF
-diff --git a/COPYING b/COPYING.1
-copy from COPYING
-copy to COPYING.1
---- a/COPYING
-+++ b/COPYING.1
-@@ -6 +6 @@
-- HOWEVER, in order to allow a migration to GPLv3 if that seems like
-+ However, in order to allow a migration to GPLv3 if that seems like
-diff --git a/COPYING b/COPYING.2
-rename from COPYING
-rename to COPYING.2
---- a/COPYING
-+++ b/COPYING.2
-@@ -2 +2 @@
-- Note that the only valid version of the GPL as far as this project
-+ Note that the only valid version of the G.P.L as far as this project
-@@ -6 +6 @@
-- HOWEVER, in order to allow a migration to GPLv3 if that seems like
-+ HOWEVER, in order to allow a migration to G.P.Lv3 if that seems like
-@@ -12 +12 @@
-- This file is licensed under the GPL v2, or a later version
-+ This file is licensed under the G.P.L v2, or a later version
-EOF
-
-test_expect_success \
- 'validate output from diff-helper (#1)' \
- 'compare_diff_patch current expected'
-
################################################################
test_expect_success \
'validate output from rename/copy detection (#2)' \
'compare_diff_raw current expected'
-# make sure diff-helper can grok it.
-mv expected diff-raw
-GIT_DIFF_OPTS=--unified=0 git-diff-helper <diff-raw >current
-cat >expected <<\EOF
-diff --git a/COPYING b/COPYING
---- a/COPYING
-+++ b/COPYING
-@@ -2 +2 @@
-- Note that the only valid version of the GPL as far as this project
-+ Note that the only valid version of the G.P.L as far as this project
-@@ -6 +6 @@
-- HOWEVER, in order to allow a migration to GPLv3 if that seems like
-+ HOWEVER, in order to allow a migration to G.P.Lv3 if that seems like
-@@ -12 +12 @@
-- This file is licensed under the GPL v2, or a later version
-+ This file is licensed under the G.P.L v2, or a later version
-diff --git a/COPYING b/COPYING.1
-copy from COPYING
-copy to COPYING.1
---- a/COPYING
-+++ b/COPYING.1
-@@ -6 +6 @@
-- HOWEVER, in order to allow a migration to GPLv3 if that seems like
-+ However, in order to allow a migration to GPLv3 if that seems like
-EOF
-
-test_expect_success \
- 'validate output from diff-helper (#2)' \
- 'compare_diff_patch current expected'
-
################################################################
# tree has COPYING and rezrov. work tree has the same COPYING and
'validate output from rename/copy detection (#3)' \
'compare_diff_raw current expected'
-# make sure diff-helper can grok it.
-mv expected diff-raw
-GIT_DIFF_OPTS=--unified=0 git-diff-helper <diff-raw >current
-cat >expected <<\EOF
-diff --git a/COPYING b/COPYING.1
-copy from COPYING
-copy to COPYING.1
---- a/COPYING
-+++ b/COPYING.1
-@@ -6 +6 @@
-- HOWEVER, in order to allow a migration to GPLv3 if that seems like
-+ However, in order to allow a migration to GPLv3 if that seems like
-EOF
-
-test_expect_success \
- 'validate output from diff-helper (#3)' \
- 'compare_diff_patch current expected'
-
test_done
'validate output from rename/copy detection (#1)' \
'compare_diff_raw_z current expected'
-# make sure diff-helper can grok it.
-mv current diff-raw
-GIT_DIFF_OPTS=--unified=0 git-diff-helper -z <diff-raw >current
-cat >expected <<\EOF
-diff --git a/COPYING b/COPYING.1
-copy from COPYING
-copy to COPYING.1
---- a/COPYING
-+++ b/COPYING.1
-@@ -6 +6 @@
-- HOWEVER, in order to allow a migration to GPLv3 if that seems like
-+ However, in order to allow a migration to GPLv3 if that seems like
-diff --git a/COPYING b/COPYING.2
-rename from COPYING
-rename to COPYING.2
---- a/COPYING
-+++ b/COPYING.2
-@@ -2 +2 @@
-- Note that the only valid version of the GPL as far as this project
-+ Note that the only valid version of the G.P.L as far as this project
-@@ -6 +6 @@
-- HOWEVER, in order to allow a migration to GPLv3 if that seems like
-+ HOWEVER, in order to allow a migration to G.P.Lv3 if that seems like
-@@ -12 +12 @@
-- This file is licensed under the GPL v2, or a later version
-+ This file is licensed under the G.P.L v2, or a later version
-EOF
-
-test_expect_success \
- 'validate output from diff-helper (#1)' \
- 'compare_diff_patch current expected'
-
################################################################
test_expect_success \
'validate output from rename/copy detection (#2)' \
'compare_diff_raw_z current expected'
-# make sure diff-helper can grok it.
-mv current diff-raw
-GIT_DIFF_OPTS=--unified=0 git-diff-helper -z <diff-raw >current
-cat >expected <<\EOF
-diff --git a/COPYING b/COPYING
---- a/COPYING
-+++ b/COPYING
-@@ -2 +2 @@
-- Note that the only valid version of the GPL as far as this project
-+ Note that the only valid version of the G.P.L as far as this project
-@@ -6 +6 @@
-- HOWEVER, in order to allow a migration to GPLv3 if that seems like
-+ HOWEVER, in order to allow a migration to G.P.Lv3 if that seems like
-@@ -12 +12 @@
-- This file is licensed under the GPL v2, or a later version
-+ This file is licensed under the G.P.L v2, or a later version
-diff --git a/COPYING b/COPYING.1
-copy from COPYING
-copy to COPYING.1
---- a/COPYING
-+++ b/COPYING.1
-@@ -6 +6 @@
-- HOWEVER, in order to allow a migration to GPLv3 if that seems like
-+ However, in order to allow a migration to GPLv3 if that seems like
-EOF
-
-test_expect_success \
- 'validate output from diff-helper (#2)' \
- 'compare_diff_patch current expected'
-
################################################################
# tree has COPYING and rezrov. work tree has the same COPYING and
'validate output from rename/copy detection (#3)' \
'compare_diff_raw_z current expected'
-# make sure diff-helper can grok it.
-mv current diff-raw
-GIT_DIFF_OPTS=--unified=0 git-diff-helper -z <diff-raw >current
-cat >expected <<\EOF
-diff --git a/COPYING b/COPYING.1
-copy from COPYING
-copy to COPYING.1
---- a/COPYING
-+++ b/COPYING.1
-@@ -6 +6 @@
-- HOWEVER, in order to allow a migration to GPLv3 if that seems like
-+ However, in order to allow a migration to GPLv3 if that seems like
-EOF
-
-test_expect_success \
- 'validate output from diff-helper (#3)' \
- 'compare_diff_patch current expected'
-
test_done
# make and install sample templates
-INSTALL=install
-prefix=$(HOME)
-template_dir=$(prefix)/share/git-core/templates/
+INSTALL ?= install
+TAR ?= tar
+prefix ?= $(HOME)
+template_dir ?= $(prefix)/share/git-core/templates/
# DESTDIR=
all: boilerplates custom
install: all
$(INSTALL) -d -m755 $(DESTDIR)$(template_dir)
- tar Ccf blt - . | tar Cxf $(DESTDIR)$(template_dir) -
+ (cd blt && $(TAR) cf - .) | \
+ (cd $(DESTDIR)$(template_dir) && $(TAR) xf -)
return 0;
}
-static int compare_data(struct cache_entry *ce, struct stat *st)
-{
- int match = -1;
- int fd = open(ce->name, O_RDONLY);
-
- if (fd >= 0) {
- unsigned char sha1[20];
- if (!index_fd(sha1, fd, st, 0, NULL))
- match = memcmp(sha1, ce->sha1, 20);
- close(fd);
- }
- return match;
-}
-
-static int compare_link(struct cache_entry *ce, unsigned long expected_size)
-{
- int match = -1;
- char *target;
- void *buffer;
- unsigned long size;
- char type[10];
- int len;
-
- target = xmalloc(expected_size);
- len = readlink(ce->name, target, expected_size);
- if (len != expected_size) {
- free(target);
- return -1;
- }
- buffer = read_sha1_file(ce->sha1, type, &size);
- if (!buffer) {
- free(target);
- return -1;
- }
- if (size == expected_size)
- match = memcmp(buffer, target, size);
- free(buffer);
- free(target);
- return match;
-}
-
/*
* "refresh" does not calculate a new sha1 file or bring the
* cache up-to-date for mode/content changes. But what it
if (!changed)
return ce;
- /*
- * If the mode or type has changed, there's no point in trying
- * to refresh the entry - it's not going to match
- */
- if (changed & (MODE_CHANGED | TYPE_CHANGED))
+ if (ce_modified(ce, &st))
return ERR_PTR(-EINVAL);
- switch (st.st_mode & S_IFMT) {
- case S_IFREG:
- if (compare_data(ce, &st))
- return ERR_PTR(-EINVAL);
- break;
- case S_IFLNK:
- if (compare_link(ce, st.st_size))
- return ERR_PTR(-EINVAL);
- break;
- default:
- return ERR_PTR(-EINVAL);
- }
-
size = ce_size(ce);
updated = xmalloc(size);
memcpy(updated, ce, size);