├── .npmignore ├── test ├── fixtures │ ├── clean │ │ ├── rawr.txt │ │ ├── iamuntracked │ │ │ └── untracked.txt │ │ ├── git.git │ │ │ ├── HEAD │ │ │ ├── refs │ │ │ │ └── heads │ │ │ │ │ ├── master │ │ │ │ │ └── f-gitCheckoutFiles │ │ │ ├── objects │ │ │ │ ├── 14 │ │ │ │ │ └── e5a1a3a459e05d486b98df2802ee4b30c33995 │ │ │ │ ├── 41 │ │ │ │ │ └── 2d321c36a34331125a77493b5dd41f5313a568 │ │ │ │ ├── 55 │ │ │ │ │ └── 80d8a9feeadf1c36a73a2778c62206314aebac │ │ │ │ ├── 56 │ │ │ │ │ └── 02c1d7079f5ff3f49f341722c6d5baf93bb26e │ │ │ │ ├── info │ │ │ │ │ └── packs │ │ │ │ ├── c2 │ │ │ │ │ └── dfadf4d76bea7fbe28086d95aa0c803237539e │ │ │ │ └── pack │ │ │ │ │ ├── pack-70f08ce8f755306c59b6d804345abf334b5586f8.idx │ │ │ │ │ └── pack-70f08ce8f755306c59b6d804345abf334b5586f8.pack │ │ │ ├── index │ │ │ └── config │ │ ├── b.coffee │ │ ├── a.coffee │ │ └── d.js │ ├── reset │ │ ├── rawr.txt │ │ ├── git.git │ │ │ ├── HEAD │ │ │ ├── refs │ │ │ │ └── heads │ │ │ │ │ ├── master │ │ │ │ │ └── f-gitCheckoutFiles │ │ │ ├── objects │ │ │ │ ├── 14 │ │ │ │ │ └── e5a1a3a459e05d486b98df2802ee4b30c33995 │ │ │ │ ├── 41 │ │ │ │ │ └── 2d321c36a34331125a77493b5dd41f5313a568 │ │ │ │ ├── 55 │ │ │ │ │ └── 80d8a9feeadf1c36a73a2778c62206314aebac │ │ │ │ ├── 56 │ │ │ │ │ └── 02c1d7079f5ff3f49f341722c6d5baf93bb26e │ │ │ │ ├── info │ │ │ │ │ └── packs │ │ │ │ ├── c2 │ │ │ │ │ └── dfadf4d76bea7fbe28086d95aa0c803237539e │ │ │ │ └── pack │ │ │ │ │ ├── pack-70f08ce8f755306c59b6d804345abf334b5586f8.idx │ │ │ │ │ └── pack-70f08ce8f755306c59b6d804345abf334b5586f8.pack │ │ │ ├── index │ │ │ └── config │ │ ├── b.coffee │ │ ├── a.coffee │ │ └── d.js │ ├── status │ │ ├── COMMIT_EDITMSG │ │ ├── HEAD │ │ ├── refs │ │ │ └── heads │ │ │ │ └── master │ │ ├── index │ │ ├── description │ │ ├── config │ │ ├── objects │ │ │ ├── 10 │ │ │ │ └── c14fdc111b6776b1fc3740e8b16939233f7a84 │ │ │ ├── 19 │ │ │ │ └── 0a18037c64c43e6b11489df4bf0b9eb6d2c9bf │ │ │ ├── 8b │ │ │ │ └── aef1b4abc478178b004d62031cf7fe6db6f903 │ │ │ ├── ac │ │ │ │ └── be86c7c89586e0912a0a851bacf309c595c308 │ │ │ ├── d8 │ │ │ │ └── b85abf216872cda37b67d8f0c2d1a6fa81a7c3 │ │ │ └── e6 │ │ │ │ └── 2415c2695333e16ce6a65eac0b0ade587fd391 │ │ ├── logs │ │ │ ├── HEAD │ │ │ └── refs │ │ │ │ └── heads │ │ │ │ └── master │ │ ├── hooks │ │ │ ├── post-commit.sample │ │ │ ├── post-update.sample │ │ │ ├── pre-applypatch.sample │ │ │ ├── applypatch-msg.sample │ │ │ ├── post-receive.sample │ │ │ ├── commit-msg.sample │ │ │ ├── prepare-commit-msg.sample │ │ │ ├── pre-commit.sample │ │ │ └── update.sample │ │ └── info │ │ │ └── exclude │ ├── tagged │ │ ├── COMMIT_EDITMSG │ │ ├── HEAD │ │ ├── refs │ │ │ ├── heads │ │ │ │ └── master │ │ │ └── tags │ │ │ │ └── tag-1 │ │ ├── index │ │ ├── description │ │ ├── config │ │ ├── objects │ │ │ ├── 12 │ │ │ │ └── d411f1066eccc420e1f0361ecf88f8e2b65f5b │ │ │ ├── 19 │ │ │ │ └── 0a18037c64c43e6b11489df4bf0b9eb6d2c9bf │ │ │ ├── 32 │ │ │ │ └── bbb351de16c3e404b3b7c77601c3d124e1e1a1 │ │ │ ├── 41 │ │ │ │ └── 0a16650aa2a129ed639f66b7ce17bd76b90e65 │ │ │ ├── 48 │ │ │ │ └── 082f72f087ce7e6fa75b9c41d7387daecd447b │ │ │ ├── 68 │ │ │ │ └── ba9551aa06079093a6b868b7fac98ed6634ec0 │ │ │ ├── 78 │ │ │ │ └── cb34985ee281f9b8008b556ad5b4dd36473b10 │ │ │ ├── 81 │ │ │ │ └── c545efebe5f57d4cab2ba9ec294c4b0cadf672 │ │ │ ├── 91 │ │ │ │ └── d6d39cd8638f1067989e0ab9c9c00ca378c952 │ │ │ ├── 2c │ │ │ │ └── 2ecd34cc1d33002db81285b50396ab597d10bd │ │ │ ├── 9f │ │ │ │ └── 358a4addefcab294b83e4282bfef1f9625a249 │ │ │ ├── bb │ │ │ │ └── fb0e8e077ab9b37941097883f4e917ecca3d33 │ │ │ ├── d0 │ │ │ │ └── 0491fd7e5bb6fa28c517a0bb32b8b506539d4d │ │ │ ├── d6 │ │ │ │ └── 68469ca17a197feaa175a83f2f3de2abb781ad │ │ │ ├── e5 │ │ │ │ └── 6e15bb7ddb6bd0b6d924b18fcee53d8713d7ea │ │ │ ├── e6 │ │ │ │ └── 380addaa18a80d1ce0ed1ebdf3417a654f6fde │ │ │ ├── ea │ │ │ │ └── 1658a2ba3f3c4f9f50fa19765ba7d0b5dcd27c │ │ │ ├── eb │ │ │ │ └── cbdf47e0ad6503d09f59cd8eeb76d9435a0396 │ │ │ └── f8 │ │ │ │ └── 44a55bbc98af479703c35aeb2837cf0e4eff1a │ │ ├── hooks │ │ │ ├── post-commit.sample │ │ │ ├── post-update.sample │ │ │ ├── pre-applypatch.sample │ │ │ ├── applypatch-msg.sample │ │ │ ├── post-receive.sample │ │ │ ├── commit-msg.sample │ │ │ ├── prepare-commit-msg.sample │ │ │ ├── pre-commit.sample │ │ │ └── update.sample │ │ ├── info │ │ │ └── exclude │ │ └── logs │ │ │ ├── HEAD │ │ │ └── refs │ │ │ └── heads │ │ │ └── master │ ├── checkout │ │ ├── COMMIT_EDITMSG │ │ ├── HEAD │ │ ├── refs │ │ │ └── heads │ │ │ │ ├── b2 │ │ │ │ ├── b3 │ │ │ │ └── master │ │ ├── description │ │ ├── index │ │ ├── config │ │ ├── objects │ │ │ ├── 5d │ │ │ │ └── 0a23d3d71875e5abe637a1b7b3b9ea050f16aa │ │ │ ├── e5 │ │ │ │ └── fa16f39fe47d5562b74c4f5912d8ef07dd126a │ │ │ └── e6 │ │ │ │ └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391 │ │ ├── logs │ │ │ └── refs │ │ │ │ └── heads │ │ │ │ ├── b2 │ │ │ │ ├── b3 │ │ │ │ └── master │ │ ├── hooks │ │ │ ├── post-commit.sample │ │ │ ├── post-update.sample │ │ │ ├── pre-applypatch.sample │ │ │ ├── applypatch-msg.sample │ │ │ ├── post-receive.sample │ │ │ ├── commit-msg.sample │ │ │ ├── prepare-commit-msg.sample │ │ │ ├── pre-commit.sample │ │ │ └── update.sample │ │ └── info │ │ │ └── exclude │ ├── remotes │ │ ├── HEAD │ │ ├── refs │ │ │ ├── remotes │ │ │ │ └── origin │ │ │ │ │ └── HEAD │ │ │ └── heads │ │ │ │ └── master │ │ ├── index │ │ ├── description │ │ ├── packed-refs │ │ ├── objects │ │ │ └── pack │ │ │ │ ├── pack-3f24024466408b565d66ecd5902c84ec2362e513.idx │ │ │ │ └── pack-3f24024466408b565d66ecd5902c84ec2362e513.pack │ │ ├── logs │ │ │ ├── HEAD │ │ │ └── refs │ │ │ │ └── heads │ │ │ │ └── master │ │ ├── hooks │ │ │ ├── post-commit.sample │ │ │ ├── post-update.sample │ │ │ ├── pre-applypatch.sample │ │ │ ├── applypatch-msg.sample │ │ │ ├── post-receive.sample │ │ │ ├── commit-msg.sample │ │ │ ├── prepare-commit-msg.sample │ │ │ ├── pre-commit.sample │ │ │ └── update.sample │ │ ├── info │ │ │ └── exclude │ │ └── config │ ├── simple │ │ ├── HEAD │ │ ├── index │ │ ├── description │ │ ├── config │ │ ├── hooks │ │ │ ├── post-commit.sample │ │ │ ├── post-update.sample │ │ │ ├── pre-applypatch.sample │ │ │ ├── applypatch-msg.sample │ │ │ ├── post-receive.sample │ │ │ ├── commit-msg.sample │ │ │ ├── prepare-commit-msg.sample │ │ │ ├── pre-commit.sample │ │ │ └── update.sample │ │ └── info │ │ │ └── exclude │ ├── status_opts │ │ ├── COMMIT_EDITMSG │ │ ├── HEAD │ │ ├── refs │ │ │ └── heads │ │ │ │ └── master │ │ ├── description │ │ ├── index │ │ ├── config │ │ ├── objects │ │ │ ├── 10 │ │ │ │ └── c14fdc111b6776b1fc3740e8b16939233f7a84 │ │ │ ├── 19 │ │ │ │ └── 0a18037c64c43e6b11489df4bf0b9eb6d2c9bf │ │ │ ├── 8b │ │ │ │ └── aef1b4abc478178b004d62031cf7fe6db6f903 │ │ │ ├── ac │ │ │ │ └── be86c7c89586e0912a0a851bacf309c595c308 │ │ │ ├── c8 │ │ │ │ └── 686e302f5c2f2300767f366cc616e9c464a1bc │ │ │ ├── d8 │ │ │ │ └── b85abf216872cda37b67d8f0c2d1a6fa81a7c3 │ │ │ └── e6 │ │ │ │ └── 2415c2695333e16ce6a65eac0b0ade587fd391 │ │ ├── logs │ │ │ ├── HEAD │ │ │ └── refs │ │ │ │ └── heads │ │ │ │ └── master │ │ ├── hooks │ │ │ ├── post-commit.sample │ │ │ ├── post-update.sample │ │ │ ├── pre-applypatch.sample │ │ │ ├── applypatch-msg.sample │ │ │ ├── post-receive.sample │ │ │ ├── commit-msg.sample │ │ │ ├── prepare-commit-msg.sample │ │ │ ├── pre-commit.sample │ │ │ └── update.sample │ │ ├── info │ │ │ └── exclude │ │ └── npm-debug.log │ ├── branched │ │ ├── COMMIT_EDITMSG │ │ ├── HEAD │ │ ├── refs │ │ │ └── heads │ │ │ │ ├── master │ │ │ │ └── something │ │ ├── description │ │ ├── index │ │ ├── config │ │ ├── objects │ │ │ ├── 17 │ │ │ │ └── 2b99dd464f6c9c101a987991fcc63491f08985 │ │ │ ├── 77 │ │ │ │ └── 83d64e077617ab7b84fe9726f721e921b9623b │ │ │ ├── 91 │ │ │ │ └── 3318e66e9beed3e89e9c402c1d6585ef3f7e6f │ │ │ ├── 6f │ │ │ │ └── 1de2421ce0427d9243bcd4ba7e38734cf96fe4 │ │ │ ├── 9a │ │ │ │ └── bc538b0dc8bf3974e04f3cb5d3f06240e8cef6 │ │ │ ├── b0 │ │ │ │ └── 45ec4b14c60f03329654266478b6e8b92b33c5 │ │ │ ├── b6 │ │ │ │ └── 1b4728ef3cb2b3de0ec0421a54d170b6b7de13 │ │ │ ├── bd │ │ │ │ └── 502d58e9f0d51bd6c880994f778d0c896e4135 │ │ │ ├── c0 │ │ │ │ └── efd1cc406c54014067a7da9ab15c6a9c1bc714 │ │ │ └── e4 │ │ │ │ └── ff69dd8f19d770e9731b4bc424ccb695f0b5ad │ │ ├── hooks │ │ │ ├── post-commit.sample │ │ │ ├── post-update.sample │ │ │ ├── pre-applypatch.sample │ │ │ ├── applypatch-msg.sample │ │ │ ├── post-receive.sample │ │ │ ├── commit-msg.sample │ │ │ ├── prepare-commit-msg.sample │ │ │ ├── pre-commit.sample │ │ │ └── update.sample │ │ ├── info │ │ │ └── exclude │ │ └── logs │ │ │ ├── refs │ │ │ └── heads │ │ │ │ ├── master │ │ │ │ └── something │ │ │ └── HEAD │ ├── gpgsigned │ │ ├── HEAD │ │ ├── description │ │ ├── refs │ │ │ └── heads │ │ │ │ └── master │ │ ├── config │ │ └── objects │ │ │ ├── 50 │ │ │ └── 702b21b3b51da55bf4006185133a4173efde62 │ │ │ ├── a5 │ │ │ └── e51a8a6b1fe4d0339c170a04c332bf0497e5bb │ │ │ ├── a7 │ │ │ └── 9e4f2537e8228361a0961f9b66108723a7679b │ │ │ ├── e6 │ │ │ └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391 │ │ │ ├── ec │ │ │ └── 2c2e08e7dd8ce60d863c5bbd9563db03487d35 │ │ │ ├── f4 │ │ │ └── 4d5893d23b79141d8b525edc1375821937b3e6 │ │ │ └── f6 │ │ │ └── 7b3352d57e26a71ccf0b35d87f6c68161f9c0a │ ├── no_branch │ │ ├── COMMIT_EDITMSG │ │ ├── HEAD │ │ ├── refs │ │ │ └── heads │ │ │ │ └── master │ │ ├── description │ │ ├── index │ │ ├── config │ │ ├── objects │ │ │ ├── bf │ │ │ │ └── 22474a42e7ee19511de6fab2107bcef7b03e5a │ │ │ ├── e6 │ │ │ │ └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391 │ │ │ └── f9 │ │ │ │ └── 3e3a1a1525fb5b91020da86e44810c87a2d7bc │ │ ├── logs │ │ │ ├── refs │ │ │ │ └── heads │ │ │ │ │ └── master │ │ │ └── HEAD │ │ ├── hooks │ │ │ ├── post-update.sample │ │ │ ├── pre-applypatch.sample │ │ │ ├── applypatch-msg.sample │ │ │ ├── commit-msg.sample │ │ │ ├── prepare-commit-msg.sample │ │ │ ├── pre-push.sample │ │ │ ├── pre-commit.sample │ │ │ └── update.sample │ │ └── info │ │ │ └── exclude │ └── submodule │ │ ├── COMMIT_EDITMSG │ │ ├── HEAD │ │ ├── refs │ │ └── heads │ │ │ └── master │ │ ├── description │ │ ├── index │ │ ├── config │ │ ├── objects │ │ ├── 45 │ │ │ └── b983be36b73c0788dc9cbcb76cbb80fc7bb057 │ │ ├── 48 │ │ │ └── 7a70ae6cae1041f9903701d0cd8c9f30dd88a9 │ │ ├── 3b │ │ │ └── 563fc33e799367e2d2824fd21e0219fc7591db │ │ ├── b0 │ │ │ └── e66a8a93b83161375f18dcdc9e9329af61e04f │ │ ├── ea │ │ │ └── 4ab982469a4a539b773a091670224343db1eee │ │ └── fb │ │ │ └── eb68ceaa10264b36573022d784137bab4fa273 │ │ ├── hooks │ │ ├── post-commit.sample │ │ ├── post-update.sample │ │ ├── pre-applypatch.sample │ │ ├── applypatch-msg.sample │ │ ├── post-receive.sample │ │ ├── commit-msg.sample │ │ ├── prepare-commit-msg.sample │ │ ├── pre-commit.sample │ │ └── update.sample │ │ ├── info │ │ └── exclude │ │ └── logs │ │ ├── HEAD │ │ └── refs │ │ └── heads │ │ └── master ├── mocha.opts ├── fixtures.coffee ├── config.test.coffee ├── tag.test.coffee ├── actor.test.coffee ├── commit.test.coffee ├── ref.test.coffee ├── status.test.coffee ├── blob.test.coffee ├── status_opts.test.coffee ├── index.test.coffee ├── tree.test.coffee └── diff.test.coffee ├── .gitattributes ├── .travis.yml ├── generate-changelog.sh ├── .gitignore ├── src ├── config.coffee ├── actor.coffee ├── status.coffee ├── blob.coffee ├── ref.coffee ├── tag.coffee ├── submodule.coffee ├── index.coffee ├── tree.coffee ├── git.coffee ├── diff.coffee └── commit.coffee ├── package.json └── LICENSE /.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | -------------------------------------------------------------------------------- /test/fixtures/clean/rawr.txt: -------------------------------------------------------------------------------- 1 | abc 2 | -------------------------------------------------------------------------------- /test/fixtures/reset/rawr.txt: -------------------------------------------------------------------------------- 1 | abc 2 | -------------------------------------------------------------------------------- /test/fixtures/clean/iamuntracked/untracked.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/status/COMMIT_EDITMSG: -------------------------------------------------------------------------------- 1 | initial 2 | -------------------------------------------------------------------------------- /test/fixtures/tagged/COMMIT_EDITMSG: -------------------------------------------------------------------------------- 1 | commit 6 2 | -------------------------------------------------------------------------------- /test/fixtures/checkout/COMMIT_EDITMSG: -------------------------------------------------------------------------------- 1 | commit 1 2 | -------------------------------------------------------------------------------- /test/fixtures/remotes/HEAD: -------------------------------------------------------------------------------- 1 | ref: refs/heads/master 2 | -------------------------------------------------------------------------------- /test/fixtures/simple/HEAD: -------------------------------------------------------------------------------- 1 | ref: refs/heads/master 2 | -------------------------------------------------------------------------------- /test/fixtures/status/HEAD: -------------------------------------------------------------------------------- 1 | ref: refs/heads/master 2 | -------------------------------------------------------------------------------- /test/fixtures/status_opts/COMMIT_EDITMSG: -------------------------------------------------------------------------------- 1 | initial 2 | -------------------------------------------------------------------------------- /test/fixtures/tagged/HEAD: -------------------------------------------------------------------------------- 1 | ref: refs/heads/master 2 | -------------------------------------------------------------------------------- /test/fixtures/branched/COMMIT_EDITMSG: -------------------------------------------------------------------------------- 1 | add a sub dir 2 | -------------------------------------------------------------------------------- /test/fixtures/branched/HEAD: -------------------------------------------------------------------------------- 1 | ref: refs/heads/master 2 | -------------------------------------------------------------------------------- /test/fixtures/checkout/HEAD: -------------------------------------------------------------------------------- 1 | ref: refs/heads/master 2 | -------------------------------------------------------------------------------- /test/fixtures/gpgsigned/HEAD: -------------------------------------------------------------------------------- 1 | ref: refs/heads/master 2 | -------------------------------------------------------------------------------- /test/fixtures/no_branch/COMMIT_EDITMSG: -------------------------------------------------------------------------------- 1 | Initial Commit. 2 | -------------------------------------------------------------------------------- /test/fixtures/status_opts/HEAD: -------------------------------------------------------------------------------- 1 | ref: refs/heads/master 2 | -------------------------------------------------------------------------------- /test/fixtures/submodule/COMMIT_EDITMSG: -------------------------------------------------------------------------------- 1 | add a submodule 2 | -------------------------------------------------------------------------------- /test/fixtures/submodule/HEAD: -------------------------------------------------------------------------------- 1 | ref: refs/heads/master 2 | -------------------------------------------------------------------------------- /test/fixtures/clean/git.git/HEAD: -------------------------------------------------------------------------------- 1 | ref: refs/heads/master 2 | -------------------------------------------------------------------------------- /test/fixtures/reset/git.git/HEAD: -------------------------------------------------------------------------------- 1 | ref: refs/heads/master 2 | -------------------------------------------------------------------------------- /test/mocha.opts: -------------------------------------------------------------------------------- 1 | -R spec 2 | --compilers coffee:coffee-script -------------------------------------------------------------------------------- /test/fixtures/no_branch/HEAD: -------------------------------------------------------------------------------- 1 | bf22474a42e7ee19511de6fab2107bcef7b03e5a 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # To avoid corrupting fixtures 2 | test/fixtures/ binary 3 | -------------------------------------------------------------------------------- /test/fixtures/checkout/refs/heads/b2: -------------------------------------------------------------------------------- 1 | 5d0a23d3d71875e5abe637a1b7b3b9ea050f16aa 2 | -------------------------------------------------------------------------------- /test/fixtures/checkout/refs/heads/b3: -------------------------------------------------------------------------------- 1 | 5d0a23d3d71875e5abe637a1b7b3b9ea050f16aa 2 | -------------------------------------------------------------------------------- /test/fixtures/remotes/refs/remotes/origin/HEAD: -------------------------------------------------------------------------------- 1 | ref: refs/remotes/origin/master 2 | -------------------------------------------------------------------------------- /test/fixtures/status/refs/heads/master: -------------------------------------------------------------------------------- 1 | 10c14fdc111b6776b1fc3740e8b16939233f7a84 2 | -------------------------------------------------------------------------------- /test/fixtures/tagged/refs/heads/master: -------------------------------------------------------------------------------- 1 | 78cb34985ee281f9b8008b556ad5b4dd36473b10 2 | -------------------------------------------------------------------------------- /test/fixtures/tagged/refs/tags/tag-1: -------------------------------------------------------------------------------- 1 | e6380addaa18a80d1ce0ed1ebdf3417a654f6fde 2 | -------------------------------------------------------------------------------- /test/fixtures/branched/refs/heads/master: -------------------------------------------------------------------------------- 1 | 913318e66e9beed3e89e9c402c1d6585ef3f7e6f 2 | -------------------------------------------------------------------------------- /test/fixtures/branched/refs/heads/something: -------------------------------------------------------------------------------- 1 | 7783d64e077617ab7b84fe9726f721e921b9623b 2 | -------------------------------------------------------------------------------- /test/fixtures/checkout/refs/heads/master: -------------------------------------------------------------------------------- 1 | 5d0a23d3d71875e5abe637a1b7b3b9ea050f16aa 2 | -------------------------------------------------------------------------------- /test/fixtures/gpgsigned/description: -------------------------------------------------------------------------------- 1 | Fixture for testing gift with gpg signed commits 2 | -------------------------------------------------------------------------------- /test/fixtures/gpgsigned/refs/heads/master: -------------------------------------------------------------------------------- 1 | ec2c2e08e7dd8ce60d863c5bbd9563db03487d35 2 | -------------------------------------------------------------------------------- /test/fixtures/no_branch/refs/heads/master: -------------------------------------------------------------------------------- 1 | bf22474a42e7ee19511de6fab2107bcef7b03e5a 2 | -------------------------------------------------------------------------------- /test/fixtures/remotes/refs/heads/master: -------------------------------------------------------------------------------- 1 | bdd3996d38d885e18e5c5960df1c2c06e34d673f 2 | -------------------------------------------------------------------------------- /test/fixtures/status_opts/refs/heads/master: -------------------------------------------------------------------------------- 1 | 10c14fdc111b6776b1fc3740e8b16939233f7a84 2 | -------------------------------------------------------------------------------- /test/fixtures/submodule/refs/heads/master: -------------------------------------------------------------------------------- 1 | fbeb68ceaa10264b36573022d784137bab4fa273 2 | -------------------------------------------------------------------------------- /test/fixtures/clean/git.git/refs/heads/master: -------------------------------------------------------------------------------- 1 | bdc76865cfc1d089ee4e238035a5860357c36506 2 | -------------------------------------------------------------------------------- /test/fixtures/reset/git.git/refs/heads/master: -------------------------------------------------------------------------------- 1 | bdc76865cfc1d089ee4e238035a5860357c36506 2 | -------------------------------------------------------------------------------- /test/fixtures/clean/git.git/refs/heads/f-gitCheckoutFiles: -------------------------------------------------------------------------------- 1 | 40216d142a8bf81e327f510990f2357dfd404486 2 | -------------------------------------------------------------------------------- /test/fixtures/reset/git.git/refs/heads/f-gitCheckoutFiles: -------------------------------------------------------------------------------- 1 | 40216d142a8bf81e327f510990f2357dfd404486 2 | -------------------------------------------------------------------------------- /test/fixtures/clean/git.git/objects/info/packs: -------------------------------------------------------------------------------- 1 | P pack-70f08ce8f755306c59b6d804345abf334b5586f8.pack 2 | 3 | -------------------------------------------------------------------------------- /test/fixtures/remotes/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/remotes/index -------------------------------------------------------------------------------- /test/fixtures/reset/git.git/objects/info/packs: -------------------------------------------------------------------------------- 1 | P pack-70f08ce8f755306c59b6d804345abf334b5586f8.pack 2 | 3 | -------------------------------------------------------------------------------- /test/fixtures/simple/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/simple/index -------------------------------------------------------------------------------- /test/fixtures/status/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/status/index -------------------------------------------------------------------------------- /test/fixtures/tagged/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/tagged/index -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - "4" 5 | - "6" 6 | - "8" 7 | - "9" 8 | -------------------------------------------------------------------------------- /test/fixtures/branched/description: -------------------------------------------------------------------------------- 1 | Unnamed repository; edit this file 'description' to name the repository. 2 | -------------------------------------------------------------------------------- /test/fixtures/branched/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/branched/index -------------------------------------------------------------------------------- /test/fixtures/checkout/description: -------------------------------------------------------------------------------- 1 | Unnamed repository; edit this file 'description' to name the repository. 2 | -------------------------------------------------------------------------------- /test/fixtures/checkout/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/checkout/index -------------------------------------------------------------------------------- /test/fixtures/gpgsigned/config: -------------------------------------------------------------------------------- 1 | [core] 2 | repositoryformatversion = 0 3 | filemode = true 4 | bare = true 5 | -------------------------------------------------------------------------------- /test/fixtures/no_branch/description: -------------------------------------------------------------------------------- 1 | Unnamed repository; edit this file 'description' to name the repository. 2 | -------------------------------------------------------------------------------- /test/fixtures/no_branch/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/no_branch/index -------------------------------------------------------------------------------- /test/fixtures/remotes/description: -------------------------------------------------------------------------------- 1 | Unnamed repository; edit this file 'description' to name the repository. 2 | -------------------------------------------------------------------------------- /test/fixtures/simple/description: -------------------------------------------------------------------------------- 1 | Unnamed repository; edit this file 'description' to name the repository. 2 | -------------------------------------------------------------------------------- /test/fixtures/status/description: -------------------------------------------------------------------------------- 1 | Unnamed repository; edit this file 'description' to name the repository. 2 | -------------------------------------------------------------------------------- /test/fixtures/submodule/description: -------------------------------------------------------------------------------- 1 | Unnamed repository; edit this file 'description' to name the repository. 2 | -------------------------------------------------------------------------------- /test/fixtures/submodule/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/submodule/index -------------------------------------------------------------------------------- /test/fixtures/tagged/description: -------------------------------------------------------------------------------- 1 | Unnamed repository; edit this file 'description' to name the repository. 2 | -------------------------------------------------------------------------------- /test/fixtures/status_opts/description: -------------------------------------------------------------------------------- 1 | Unnamed repository; edit this file 'description' to name the repository. 2 | -------------------------------------------------------------------------------- /test/fixtures/status_opts/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/status_opts/index -------------------------------------------------------------------------------- /test/fixtures/clean/git.git/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/clean/git.git/index -------------------------------------------------------------------------------- /test/fixtures/reset/git.git/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/reset/git.git/index -------------------------------------------------------------------------------- /test/fixtures/remotes/packed-refs: -------------------------------------------------------------------------------- 1 | # pack-refs with: peeled 2 | bdd3996d38d885e18e5c5960df1c2c06e34d673f refs/remotes/origin/master 3 | -------------------------------------------------------------------------------- /generate-changelog.sh: -------------------------------------------------------------------------------- 1 | pwd 2 | echo "generating CHANGELOG.md ..." 3 | github-changes -o notatestuser -r gift -b master -f CHANGELOG.md 4 | 5 | -------------------------------------------------------------------------------- /test/fixtures/branched/config: -------------------------------------------------------------------------------- 1 | [core] 2 | repositoryformatversion = 0 3 | filemode = true 4 | bare = false 5 | logallrefupdates = true 6 | -------------------------------------------------------------------------------- /test/fixtures/checkout/config: -------------------------------------------------------------------------------- 1 | [core] 2 | repositoryformatversion = 0 3 | filemode = true 4 | bare = false 5 | logallrefupdates = true 6 | -------------------------------------------------------------------------------- /test/fixtures/simple/config: -------------------------------------------------------------------------------- 1 | [core] 2 | repositoryformatversion = 0 3 | filemode = true 4 | bare = false 5 | logallrefupdates = true 6 | -------------------------------------------------------------------------------- /test/fixtures/status/config: -------------------------------------------------------------------------------- 1 | [core] 2 | repositoryformatversion = 0 3 | filemode = true 4 | bare = false 5 | logallrefupdates = true 6 | -------------------------------------------------------------------------------- /test/fixtures/submodule/config: -------------------------------------------------------------------------------- 1 | [core] 2 | repositoryformatversion = 0 3 | filemode = true 4 | bare = false 5 | logallrefupdates = true 6 | -------------------------------------------------------------------------------- /test/fixtures/tagged/config: -------------------------------------------------------------------------------- 1 | [core] 2 | repositoryformatversion = 0 3 | filemode = true 4 | bare = false 5 | logallrefupdates = true 6 | -------------------------------------------------------------------------------- /test/fixtures/clean/git.git/config: -------------------------------------------------------------------------------- 1 | [core] 2 | repositoryformatversion = 0 3 | filemode = true 4 | bare = false 5 | logallrefupdates = true 6 | -------------------------------------------------------------------------------- /test/fixtures/reset/git.git/config: -------------------------------------------------------------------------------- 1 | [core] 2 | repositoryformatversion = 0 3 | filemode = true 4 | bare = false 5 | logallrefupdates = true 6 | -------------------------------------------------------------------------------- /test/fixtures/status_opts/config: -------------------------------------------------------------------------------- 1 | [core] 2 | repositoryformatversion = 0 3 | filemode = true 4 | bare = false 5 | logallrefupdates = true 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ignore emacs and other editor files 2 | *~ 3 | \#*\# 4 | .\#* 5 | *.swp 6 | *.swo 7 | 8 | src/*.js 9 | test/*.js 10 | 11 | lib/ 12 | node_modules/ 13 | 14 | -------------------------------------------------------------------------------- /test/fixtures/status/objects/10/c14fdc111b6776b1fc3740e8b16939233f7a84: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/status/objects/10/c14fdc111b6776b1fc3740e8b16939233f7a84 -------------------------------------------------------------------------------- /test/fixtures/status/objects/19/0a18037c64c43e6b11489df4bf0b9eb6d2c9bf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/status/objects/19/0a18037c64c43e6b11489df4bf0b9eb6d2c9bf -------------------------------------------------------------------------------- /test/fixtures/status/objects/8b/aef1b4abc478178b004d62031cf7fe6db6f903: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/status/objects/8b/aef1b4abc478178b004d62031cf7fe6db6f903 -------------------------------------------------------------------------------- /test/fixtures/status/objects/ac/be86c7c89586e0912a0a851bacf309c595c308: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/status/objects/ac/be86c7c89586e0912a0a851bacf309c595c308 -------------------------------------------------------------------------------- /test/fixtures/status/objects/d8/b85abf216872cda37b67d8f0c2d1a6fa81a7c3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/status/objects/d8/b85abf216872cda37b67d8f0c2d1a6fa81a7c3 -------------------------------------------------------------------------------- /test/fixtures/status/objects/e6/2415c2695333e16ce6a65eac0b0ade587fd391: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/status/objects/e6/2415c2695333e16ce6a65eac0b0ade587fd391 -------------------------------------------------------------------------------- /test/fixtures/tagged/objects/12/d411f1066eccc420e1f0361ecf88f8e2b65f5b: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/tagged/objects/12/d411f1066eccc420e1f0361ecf88f8e2b65f5b -------------------------------------------------------------------------------- /test/fixtures/tagged/objects/19/0a18037c64c43e6b11489df4bf0b9eb6d2c9bf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/tagged/objects/19/0a18037c64c43e6b11489df4bf0b9eb6d2c9bf -------------------------------------------------------------------------------- /test/fixtures/tagged/objects/2c/2ecd34cc1d33002db81285b50396ab597d10bd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/tagged/objects/2c/2ecd34cc1d33002db81285b50396ab597d10bd -------------------------------------------------------------------------------- /test/fixtures/tagged/objects/32/bbb351de16c3e404b3b7c77601c3d124e1e1a1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/tagged/objects/32/bbb351de16c3e404b3b7c77601c3d124e1e1a1 -------------------------------------------------------------------------------- /test/fixtures/tagged/objects/41/0a16650aa2a129ed639f66b7ce17bd76b90e65: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/tagged/objects/41/0a16650aa2a129ed639f66b7ce17bd76b90e65 -------------------------------------------------------------------------------- /test/fixtures/tagged/objects/48/082f72f087ce7e6fa75b9c41d7387daecd447b: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/tagged/objects/48/082f72f087ce7e6fa75b9c41d7387daecd447b -------------------------------------------------------------------------------- /test/fixtures/tagged/objects/68/ba9551aa06079093a6b868b7fac98ed6634ec0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/tagged/objects/68/ba9551aa06079093a6b868b7fac98ed6634ec0 -------------------------------------------------------------------------------- /test/fixtures/tagged/objects/78/cb34985ee281f9b8008b556ad5b4dd36473b10: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/tagged/objects/78/cb34985ee281f9b8008b556ad5b4dd36473b10 -------------------------------------------------------------------------------- /test/fixtures/tagged/objects/81/c545efebe5f57d4cab2ba9ec294c4b0cadf672: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/tagged/objects/81/c545efebe5f57d4cab2ba9ec294c4b0cadf672 -------------------------------------------------------------------------------- /test/fixtures/tagged/objects/91/d6d39cd8638f1067989e0ab9c9c00ca378c952: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/tagged/objects/91/d6d39cd8638f1067989e0ab9c9c00ca378c952 -------------------------------------------------------------------------------- /test/fixtures/tagged/objects/9f/358a4addefcab294b83e4282bfef1f9625a249: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/tagged/objects/9f/358a4addefcab294b83e4282bfef1f9625a249 -------------------------------------------------------------------------------- /test/fixtures/tagged/objects/bb/fb0e8e077ab9b37941097883f4e917ecca3d33: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/tagged/objects/bb/fb0e8e077ab9b37941097883f4e917ecca3d33 -------------------------------------------------------------------------------- /test/fixtures/tagged/objects/d0/0491fd7e5bb6fa28c517a0bb32b8b506539d4d: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/tagged/objects/d0/0491fd7e5bb6fa28c517a0bb32b8b506539d4d -------------------------------------------------------------------------------- /test/fixtures/tagged/objects/d6/68469ca17a197feaa175a83f2f3de2abb781ad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/tagged/objects/d6/68469ca17a197feaa175a83f2f3de2abb781ad -------------------------------------------------------------------------------- /test/fixtures/tagged/objects/e5/6e15bb7ddb6bd0b6d924b18fcee53d8713d7ea: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/tagged/objects/e5/6e15bb7ddb6bd0b6d924b18fcee53d8713d7ea -------------------------------------------------------------------------------- /test/fixtures/tagged/objects/e6/380addaa18a80d1ce0ed1ebdf3417a654f6fde: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/tagged/objects/e6/380addaa18a80d1ce0ed1ebdf3417a654f6fde -------------------------------------------------------------------------------- /test/fixtures/tagged/objects/ea/1658a2ba3f3c4f9f50fa19765ba7d0b5dcd27c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/tagged/objects/ea/1658a2ba3f3c4f9f50fa19765ba7d0b5dcd27c -------------------------------------------------------------------------------- /test/fixtures/tagged/objects/eb/cbdf47e0ad6503d09f59cd8eeb76d9435a0396: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/tagged/objects/eb/cbdf47e0ad6503d09f59cd8eeb76d9435a0396 -------------------------------------------------------------------------------- /test/fixtures/tagged/objects/f8/44a55bbc98af479703c35aeb2837cf0e4eff1a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/tagged/objects/f8/44a55bbc98af479703c35aeb2837cf0e4eff1a -------------------------------------------------------------------------------- /test/fixtures/branched/objects/17/2b99dd464f6c9c101a987991fcc63491f08985: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/branched/objects/17/2b99dd464f6c9c101a987991fcc63491f08985 -------------------------------------------------------------------------------- /test/fixtures/branched/objects/6f/1de2421ce0427d9243bcd4ba7e38734cf96fe4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/branched/objects/6f/1de2421ce0427d9243bcd4ba7e38734cf96fe4 -------------------------------------------------------------------------------- /test/fixtures/branched/objects/77/83d64e077617ab7b84fe9726f721e921b9623b: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/branched/objects/77/83d64e077617ab7b84fe9726f721e921b9623b -------------------------------------------------------------------------------- /test/fixtures/branched/objects/91/3318e66e9beed3e89e9c402c1d6585ef3f7e6f: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/branched/objects/91/3318e66e9beed3e89e9c402c1d6585ef3f7e6f -------------------------------------------------------------------------------- /test/fixtures/branched/objects/9a/bc538b0dc8bf3974e04f3cb5d3f06240e8cef6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/branched/objects/9a/bc538b0dc8bf3974e04f3cb5d3f06240e8cef6 -------------------------------------------------------------------------------- /test/fixtures/branched/objects/b0/45ec4b14c60f03329654266478b6e8b92b33c5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/branched/objects/b0/45ec4b14c60f03329654266478b6e8b92b33c5 -------------------------------------------------------------------------------- /test/fixtures/branched/objects/b6/1b4728ef3cb2b3de0ec0421a54d170b6b7de13: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/branched/objects/b6/1b4728ef3cb2b3de0ec0421a54d170b6b7de13 -------------------------------------------------------------------------------- /test/fixtures/branched/objects/bd/502d58e9f0d51bd6c880994f778d0c896e4135: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/branched/objects/bd/502d58e9f0d51bd6c880994f778d0c896e4135 -------------------------------------------------------------------------------- /test/fixtures/branched/objects/c0/efd1cc406c54014067a7da9ab15c6a9c1bc714: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/branched/objects/c0/efd1cc406c54014067a7da9ab15c6a9c1bc714 -------------------------------------------------------------------------------- /test/fixtures/branched/objects/e4/ff69dd8f19d770e9731b4bc424ccb695f0b5ad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/branched/objects/e4/ff69dd8f19d770e9731b4bc424ccb695f0b5ad -------------------------------------------------------------------------------- /test/fixtures/checkout/objects/5d/0a23d3d71875e5abe637a1b7b3b9ea050f16aa: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/checkout/objects/5d/0a23d3d71875e5abe637a1b7b3b9ea050f16aa -------------------------------------------------------------------------------- /test/fixtures/checkout/objects/e5/fa16f39fe47d5562b74c4f5912d8ef07dd126a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/checkout/objects/e5/fa16f39fe47d5562b74c4f5912d8ef07dd126a -------------------------------------------------------------------------------- /test/fixtures/checkout/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/checkout/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 -------------------------------------------------------------------------------- /test/fixtures/no_branch/config: -------------------------------------------------------------------------------- 1 | [core] 2 | repositoryformatversion = 0 3 | filemode = true 4 | bare = false 5 | logallrefupdates = true 6 | ignorecase = true 7 | precomposeunicode = true 8 | -------------------------------------------------------------------------------- /test/fixtures/gpgsigned/objects/50/702b21b3b51da55bf4006185133a4173efde62: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/gpgsigned/objects/50/702b21b3b51da55bf4006185133a4173efde62 -------------------------------------------------------------------------------- /test/fixtures/gpgsigned/objects/a5/e51a8a6b1fe4d0339c170a04c332bf0497e5bb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/gpgsigned/objects/a5/e51a8a6b1fe4d0339c170a04c332bf0497e5bb -------------------------------------------------------------------------------- /test/fixtures/gpgsigned/objects/a7/9e4f2537e8228361a0961f9b66108723a7679b: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/gpgsigned/objects/a7/9e4f2537e8228361a0961f9b66108723a7679b -------------------------------------------------------------------------------- /test/fixtures/gpgsigned/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/gpgsigned/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 -------------------------------------------------------------------------------- /test/fixtures/gpgsigned/objects/ec/2c2e08e7dd8ce60d863c5bbd9563db03487d35: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/gpgsigned/objects/ec/2c2e08e7dd8ce60d863c5bbd9563db03487d35 -------------------------------------------------------------------------------- /test/fixtures/gpgsigned/objects/f4/4d5893d23b79141d8b525edc1375821937b3e6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/gpgsigned/objects/f4/4d5893d23b79141d8b525edc1375821937b3e6 -------------------------------------------------------------------------------- /test/fixtures/gpgsigned/objects/f6/7b3352d57e26a71ccf0b35d87f6c68161f9c0a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/gpgsigned/objects/f6/7b3352d57e26a71ccf0b35d87f6c68161f9c0a -------------------------------------------------------------------------------- /test/fixtures/no_branch/objects/bf/22474a42e7ee19511de6fab2107bcef7b03e5a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/no_branch/objects/bf/22474a42e7ee19511de6fab2107bcef7b03e5a -------------------------------------------------------------------------------- /test/fixtures/no_branch/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/no_branch/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 -------------------------------------------------------------------------------- /test/fixtures/no_branch/objects/f9/3e3a1a1525fb5b91020da86e44810c87a2d7bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/no_branch/objects/f9/3e3a1a1525fb5b91020da86e44810c87a2d7bc -------------------------------------------------------------------------------- /test/fixtures/status/logs/HEAD: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 10c14fdc111b6776b1fc3740e8b16939233f7a84 sentientwaffle 1329174405 -0700 commit (initial): initial 2 | -------------------------------------------------------------------------------- /test/fixtures/status_opts/objects/10/c14fdc111b6776b1fc3740e8b16939233f7a84: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/status_opts/objects/10/c14fdc111b6776b1fc3740e8b16939233f7a84 -------------------------------------------------------------------------------- /test/fixtures/status_opts/objects/19/0a18037c64c43e6b11489df4bf0b9eb6d2c9bf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/status_opts/objects/19/0a18037c64c43e6b11489df4bf0b9eb6d2c9bf -------------------------------------------------------------------------------- /test/fixtures/status_opts/objects/8b/aef1b4abc478178b004d62031cf7fe6db6f903: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/status_opts/objects/8b/aef1b4abc478178b004d62031cf7fe6db6f903 -------------------------------------------------------------------------------- /test/fixtures/status_opts/objects/ac/be86c7c89586e0912a0a851bacf309c595c308: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/status_opts/objects/ac/be86c7c89586e0912a0a851bacf309c595c308 -------------------------------------------------------------------------------- /test/fixtures/status_opts/objects/c8/686e302f5c2f2300767f366cc616e9c464a1bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/status_opts/objects/c8/686e302f5c2f2300767f366cc616e9c464a1bc -------------------------------------------------------------------------------- /test/fixtures/status_opts/objects/d8/b85abf216872cda37b67d8f0c2d1a6fa81a7c3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/status_opts/objects/d8/b85abf216872cda37b67d8f0c2d1a6fa81a7c3 -------------------------------------------------------------------------------- /test/fixtures/status_opts/objects/e6/2415c2695333e16ce6a65eac0b0ade587fd391: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/status_opts/objects/e6/2415c2695333e16ce6a65eac0b0ade587fd391 -------------------------------------------------------------------------------- /test/fixtures/submodule/objects/3b/563fc33e799367e2d2824fd21e0219fc7591db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/submodule/objects/3b/563fc33e799367e2d2824fd21e0219fc7591db -------------------------------------------------------------------------------- /test/fixtures/submodule/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/submodule/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 -------------------------------------------------------------------------------- /test/fixtures/submodule/objects/48/7a70ae6cae1041f9903701d0cd8c9f30dd88a9: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/submodule/objects/48/7a70ae6cae1041f9903701d0cd8c9f30dd88a9 -------------------------------------------------------------------------------- /test/fixtures/submodule/objects/b0/e66a8a93b83161375f18dcdc9e9329af61e04f: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/submodule/objects/b0/e66a8a93b83161375f18dcdc9e9329af61e04f -------------------------------------------------------------------------------- /test/fixtures/submodule/objects/ea/4ab982469a4a539b773a091670224343db1eee: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/submodule/objects/ea/4ab982469a4a539b773a091670224343db1eee -------------------------------------------------------------------------------- /test/fixtures/submodule/objects/fb/eb68ceaa10264b36573022d784137bab4fa273: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/submodule/objects/fb/eb68ceaa10264b36573022d784137bab4fa273 -------------------------------------------------------------------------------- /test/fixtures/clean/git.git/objects/14/e5a1a3a459e05d486b98df2802ee4b30c33995: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/clean/git.git/objects/14/e5a1a3a459e05d486b98df2802ee4b30c33995 -------------------------------------------------------------------------------- /test/fixtures/clean/git.git/objects/41/2d321c36a34331125a77493b5dd41f5313a568: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/clean/git.git/objects/41/2d321c36a34331125a77493b5dd41f5313a568 -------------------------------------------------------------------------------- /test/fixtures/clean/git.git/objects/55/80d8a9feeadf1c36a73a2778c62206314aebac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/clean/git.git/objects/55/80d8a9feeadf1c36a73a2778c62206314aebac -------------------------------------------------------------------------------- /test/fixtures/clean/git.git/objects/56/02c1d7079f5ff3f49f341722c6d5baf93bb26e: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/clean/git.git/objects/56/02c1d7079f5ff3f49f341722c6d5baf93bb26e -------------------------------------------------------------------------------- /test/fixtures/clean/git.git/objects/c2/dfadf4d76bea7fbe28086d95aa0c803237539e: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/clean/git.git/objects/c2/dfadf4d76bea7fbe28086d95aa0c803237539e -------------------------------------------------------------------------------- /test/fixtures/reset/git.git/objects/14/e5a1a3a459e05d486b98df2802ee4b30c33995: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/reset/git.git/objects/14/e5a1a3a459e05d486b98df2802ee4b30c33995 -------------------------------------------------------------------------------- /test/fixtures/reset/git.git/objects/41/2d321c36a34331125a77493b5dd41f5313a568: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/reset/git.git/objects/41/2d321c36a34331125a77493b5dd41f5313a568 -------------------------------------------------------------------------------- /test/fixtures/reset/git.git/objects/55/80d8a9feeadf1c36a73a2778c62206314aebac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/reset/git.git/objects/55/80d8a9feeadf1c36a73a2778c62206314aebac -------------------------------------------------------------------------------- /test/fixtures/reset/git.git/objects/56/02c1d7079f5ff3f49f341722c6d5baf93bb26e: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/reset/git.git/objects/56/02c1d7079f5ff3f49f341722c6d5baf93bb26e -------------------------------------------------------------------------------- /test/fixtures/reset/git.git/objects/c2/dfadf4d76bea7fbe28086d95aa0c803237539e: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/reset/git.git/objects/c2/dfadf4d76bea7fbe28086d95aa0c803237539e -------------------------------------------------------------------------------- /test/fixtures/status_opts/logs/HEAD: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 10c14fdc111b6776b1fc3740e8b16939233f7a84 sentientwaffle 1329174405 -0700 commit (initial): initial 2 | -------------------------------------------------------------------------------- /test/fixtures/checkout/logs/refs/heads/b2: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 5d0a23d3d71875e5abe637a1b7b3b9ea050f16aa sentientwaffle 1329248175 -0700 branch: Created from HEAD 2 | -------------------------------------------------------------------------------- /test/fixtures/checkout/logs/refs/heads/b3: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 5d0a23d3d71875e5abe637a1b7b3b9ea050f16aa sentientwaffle 1329248189 -0700 branch: Created from HEAD 2 | -------------------------------------------------------------------------------- /test/fixtures/checkout/logs/refs/heads/master: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 5d0a23d3d71875e5abe637a1b7b3b9ea050f16aa sentientwaffle 1329248161 -0700 commit (initial): commit 1 2 | -------------------------------------------------------------------------------- /test/fixtures/no_branch/logs/refs/heads/master: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 bf22474a42e7ee19511de6fab2107bcef7b03e5a Shaoshing 1404767269 -0400 commit (initial): Initial Commit. 2 | -------------------------------------------------------------------------------- /test/fixtures/status/logs/refs/heads/master: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 10c14fdc111b6776b1fc3740e8b16939233f7a84 sentientwaffle 1329174405 -0700 commit (initial): initial 2 | -------------------------------------------------------------------------------- /test/fixtures/remotes/objects/pack/pack-3f24024466408b565d66ecd5902c84ec2362e513.idx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/remotes/objects/pack/pack-3f24024466408b565d66ecd5902c84ec2362e513.idx -------------------------------------------------------------------------------- /test/fixtures/remotes/objects/pack/pack-3f24024466408b565d66ecd5902c84ec2362e513.pack: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/remotes/objects/pack/pack-3f24024466408b565d66ecd5902c84ec2362e513.pack -------------------------------------------------------------------------------- /test/fixtures/status_opts/logs/refs/heads/master: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 10c14fdc111b6776b1fc3740e8b16939233f7a84 sentientwaffle 1329174405 -0700 commit (initial): initial 2 | -------------------------------------------------------------------------------- /test/fixtures/remotes/logs/HEAD: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 bdd3996d38d885e18e5c5960df1c2c06e34d673f sentientwaffle 1329101708 -0700 clone: from git@github.com:octocat/Spoon-Knife.git 2 | -------------------------------------------------------------------------------- /test/fixtures/clean/git.git/objects/pack/pack-70f08ce8f755306c59b6d804345abf334b5586f8.idx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/clean/git.git/objects/pack/pack-70f08ce8f755306c59b6d804345abf334b5586f8.idx -------------------------------------------------------------------------------- /test/fixtures/reset/git.git/objects/pack/pack-70f08ce8f755306c59b6d804345abf334b5586f8.idx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/reset/git.git/objects/pack/pack-70f08ce8f755306c59b6d804345abf334b5586f8.idx -------------------------------------------------------------------------------- /test/fixtures/clean/git.git/objects/pack/pack-70f08ce8f755306c59b6d804345abf334b5586f8.pack: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/clean/git.git/objects/pack/pack-70f08ce8f755306c59b6d804345abf334b5586f8.pack -------------------------------------------------------------------------------- /test/fixtures/remotes/hooks/post-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script that is called after a successful 4 | # commit is made. 5 | # 6 | # To enable this hook, rename this file to "post-commit". 7 | 8 | : Nothing 9 | -------------------------------------------------------------------------------- /test/fixtures/reset/git.git/objects/pack/pack-70f08ce8f755306c59b6d804345abf334b5586f8.pack: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notatestuser/gift/HEAD/test/fixtures/reset/git.git/objects/pack/pack-70f08ce8f755306c59b6d804345abf334b5586f8.pack -------------------------------------------------------------------------------- /test/fixtures/simple/hooks/post-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script that is called after a successful 4 | # commit is made. 5 | # 6 | # To enable this hook, rename this file to "post-commit". 7 | 8 | : Nothing 9 | -------------------------------------------------------------------------------- /test/fixtures/status/hooks/post-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script that is called after a successful 4 | # commit is made. 5 | # 6 | # To enable this hook, rename this file to "post-commit". 7 | 8 | : Nothing 9 | -------------------------------------------------------------------------------- /test/fixtures/tagged/hooks/post-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script that is called after a successful 4 | # commit is made. 5 | # 6 | # To enable this hook, rename this file to "post-commit". 7 | 8 | : Nothing 9 | -------------------------------------------------------------------------------- /test/fixtures/branched/hooks/post-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script that is called after a successful 4 | # commit is made. 5 | # 6 | # To enable this hook, rename this file to "post-commit". 7 | 8 | : Nothing 9 | -------------------------------------------------------------------------------- /test/fixtures/checkout/hooks/post-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script that is called after a successful 4 | # commit is made. 5 | # 6 | # To enable this hook, rename this file to "post-commit". 7 | 8 | : Nothing 9 | -------------------------------------------------------------------------------- /test/fixtures/remotes/logs/refs/heads/master: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 bdd3996d38d885e18e5c5960df1c2c06e34d673f sentientwaffle 1329101708 -0700 clone: from git@github.com:octocat/Spoon-Knife.git 2 | -------------------------------------------------------------------------------- /test/fixtures/status_opts/hooks/post-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script that is called after a successful 4 | # commit is made. 5 | # 6 | # To enable this hook, rename this file to "post-commit". 7 | 8 | : Nothing 9 | -------------------------------------------------------------------------------- /test/fixtures/submodule/hooks/post-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script that is called after a successful 4 | # commit is made. 5 | # 6 | # To enable this hook, rename this file to "post-commit". 7 | 8 | : Nothing 9 | -------------------------------------------------------------------------------- /test/fixtures/clean/b.coffee: -------------------------------------------------------------------------------- 1 | grade = (student) -> 2 | if student.excellentWork 3 | "A+" 4 | else if student.okayStuff 5 | if student.triedHard then "B" else "B-" 6 | else 7 | "C" 8 | 9 | eldest = if 24 > 21 then "Liz" else "Ike" 10 | -------------------------------------------------------------------------------- /test/fixtures/reset/b.coffee: -------------------------------------------------------------------------------- 1 | grade = (student) -> 2 | if student.excellentWork 3 | "A+" 4 | else if student.okayStuff 5 | if student.triedHard then "B" else "B-" 6 | else 7 | "C" 8 | 9 | eldest = if 24 > 21 then "Liz" else "Ike" 10 | -------------------------------------------------------------------------------- /test/fixtures/branched/hooks/post-update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare a packed repository for use over 4 | # dumb transports. 5 | # 6 | # To enable this hook, rename this file to "post-update". 7 | 8 | exec git-update-server-info 9 | -------------------------------------------------------------------------------- /test/fixtures/checkout/hooks/post-update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare a packed repository for use over 4 | # dumb transports. 5 | # 6 | # To enable this hook, rename this file to "post-update". 7 | 8 | exec git-update-server-info 9 | -------------------------------------------------------------------------------- /test/fixtures/remotes/hooks/post-update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare a packed repository for use over 4 | # dumb transports. 5 | # 6 | # To enable this hook, rename this file to "post-update". 7 | 8 | exec git-update-server-info 9 | -------------------------------------------------------------------------------- /test/fixtures/simple/hooks/post-update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare a packed repository for use over 4 | # dumb transports. 5 | # 6 | # To enable this hook, rename this file to "post-update". 7 | 8 | exec git-update-server-info 9 | -------------------------------------------------------------------------------- /test/fixtures/status/hooks/post-update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare a packed repository for use over 4 | # dumb transports. 5 | # 6 | # To enable this hook, rename this file to "post-update". 7 | 8 | exec git-update-server-info 9 | -------------------------------------------------------------------------------- /test/fixtures/tagged/hooks/post-update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare a packed repository for use over 4 | # dumb transports. 5 | # 6 | # To enable this hook, rename this file to "post-update". 7 | 8 | exec git-update-server-info 9 | -------------------------------------------------------------------------------- /test/fixtures/no_branch/hooks/post-update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare a packed repository for use over 4 | # dumb transports. 5 | # 6 | # To enable this hook, rename this file to "post-update". 7 | 8 | exec git update-server-info 9 | -------------------------------------------------------------------------------- /test/fixtures/status_opts/hooks/post-update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare a packed repository for use over 4 | # dumb transports. 5 | # 6 | # To enable this hook, rename this file to "post-update". 7 | 8 | exec git-update-server-info 9 | -------------------------------------------------------------------------------- /test/fixtures/submodule/hooks/post-update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare a packed repository for use over 4 | # dumb transports. 5 | # 6 | # To enable this hook, rename this file to "post-update". 7 | 8 | exec git-update-server-info 9 | -------------------------------------------------------------------------------- /test/fixtures/remotes/info/exclude: -------------------------------------------------------------------------------- 1 | # git-ls-files --others --exclude-from=.git/info/exclude 2 | # Lines that start with '#' are comments. 3 | # For a project mostly in C, the following would be a good set of 4 | # exclude patterns (uncomment them if you want to use them): 5 | # *.[oa] 6 | # *~ 7 | -------------------------------------------------------------------------------- /test/fixtures/simple/info/exclude: -------------------------------------------------------------------------------- 1 | # git-ls-files --others --exclude-from=.git/info/exclude 2 | # Lines that start with '#' are comments. 3 | # For a project mostly in C, the following would be a good set of 4 | # exclude patterns (uncomment them if you want to use them): 5 | # *.[oa] 6 | # *~ 7 | -------------------------------------------------------------------------------- /test/fixtures/status/info/exclude: -------------------------------------------------------------------------------- 1 | # git-ls-files --others --exclude-from=.git/info/exclude 2 | # Lines that start with '#' are comments. 3 | # For a project mostly in C, the following would be a good set of 4 | # exclude patterns (uncomment them if you want to use them): 5 | # *.[oa] 6 | # *~ 7 | -------------------------------------------------------------------------------- /test/fixtures/tagged/info/exclude: -------------------------------------------------------------------------------- 1 | # git-ls-files --others --exclude-from=.git/info/exclude 2 | # Lines that start with '#' are comments. 3 | # For a project mostly in C, the following would be a good set of 4 | # exclude patterns (uncomment them if you want to use them): 5 | # *.[oa] 6 | # *~ 7 | -------------------------------------------------------------------------------- /test/fixtures/branched/info/exclude: -------------------------------------------------------------------------------- 1 | # git-ls-files --others --exclude-from=.git/info/exclude 2 | # Lines that start with '#' are comments. 3 | # For a project mostly in C, the following would be a good set of 4 | # exclude patterns (uncomment them if you want to use them): 5 | # *.[oa] 6 | # *~ 7 | -------------------------------------------------------------------------------- /test/fixtures/checkout/info/exclude: -------------------------------------------------------------------------------- 1 | # git-ls-files --others --exclude-from=.git/info/exclude 2 | # Lines that start with '#' are comments. 3 | # For a project mostly in C, the following would be a good set of 4 | # exclude patterns (uncomment them if you want to use them): 5 | # *.[oa] 6 | # *~ 7 | -------------------------------------------------------------------------------- /test/fixtures/no_branch/info/exclude: -------------------------------------------------------------------------------- 1 | # git ls-files --others --exclude-from=.git/info/exclude 2 | # Lines that start with '#' are comments. 3 | # For a project mostly in C, the following would be a good set of 4 | # exclude patterns (uncomment them if you want to use them): 5 | # *.[oa] 6 | # *~ 7 | -------------------------------------------------------------------------------- /test/fixtures/status_opts/info/exclude: -------------------------------------------------------------------------------- 1 | # git-ls-files --others --exclude-from=.git/info/exclude 2 | # Lines that start with '#' are comments. 3 | # For a project mostly in C, the following would be a good set of 4 | # exclude patterns (uncomment them if you want to use them): 5 | # *.[oa] 6 | # *~ 7 | -------------------------------------------------------------------------------- /test/fixtures/submodule/info/exclude: -------------------------------------------------------------------------------- 1 | # git-ls-files --others --exclude-from=.git/info/exclude 2 | # Lines that start with '#' are comments. 3 | # For a project mostly in C, the following would be a good set of 4 | # exclude patterns (uncomment them if you want to use them): 5 | # *.[oa] 6 | # *~ 7 | -------------------------------------------------------------------------------- /test/fixtures/remotes/config: -------------------------------------------------------------------------------- 1 | [core] 2 | repositoryformatversion = 0 3 | filemode = true 4 | bare = false 5 | logallrefupdates = true 6 | [remote "origin"] 7 | fetch = +refs/heads/*:refs/remotes/origin/* 8 | url = git@github.com:octocat/Spoon-Knife.git 9 | [branch "master"] 10 | remote = origin 11 | merge = refs/heads/master 12 | -------------------------------------------------------------------------------- /test/fixtures/submodule/logs/HEAD: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 ea4ab982469a4a539b773a091670224343db1eee sentientwaffle 1329251828 -0700 commit (initial): initial 2 | ea4ab982469a4a539b773a091670224343db1eee fbeb68ceaa10264b36573022d784137bab4fa273 sentientwaffle 1329252042 -0700 commit: add a submodule 3 | -------------------------------------------------------------------------------- /test/fixtures/branched/logs/refs/heads/master: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 b045ec4b14c60f03329654266478b6e8b92b33c5 sentientwaffle 1328999490 -0700 commit (initial): 1 2 | b045ec4b14c60f03329654266478b6e8b92b33c5 913318e66e9beed3e89e9c402c1d6585ef3f7e6f sentientwaffle 1329013671 -0700 commit: add a sub dir 3 | -------------------------------------------------------------------------------- /test/fixtures/branched/logs/refs/heads/something: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 b045ec4b14c60f03329654266478b6e8b92b33c5 sentientwaffle 1328999503 -0700 branch: Created from HEAD 2 | b045ec4b14c60f03329654266478b6e8b92b33c5 7783d64e077617ab7b84fe9726f721e921b9623b sentientwaffle 1328999518 -0700 commit: 2 3 | -------------------------------------------------------------------------------- /test/fixtures/submodule/logs/refs/heads/master: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 ea4ab982469a4a539b773a091670224343db1eee sentientwaffle 1329251828 -0700 commit (initial): initial 2 | ea4ab982469a4a539b773a091670224343db1eee fbeb68ceaa10264b36573022d784137bab4fa273 sentientwaffle 1329252042 -0700 commit: add a submodule 3 | -------------------------------------------------------------------------------- /test/fixtures/no_branch/logs/HEAD: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 bf22474a42e7ee19511de6fab2107bcef7b03e5a Shaoshing 1404767269 -0400 commit (initial): Initial Commit. 2 | bf22474a42e7ee19511de6fab2107bcef7b03e5a bf22474a42e7ee19511de6fab2107bcef7b03e5a Shaoshing 1404767281 -0400 checkout: moving from master to bf22474a42e7ee19511de6fab2107bcef7b03e5a 3 | -------------------------------------------------------------------------------- /test/fixtures/remotes/hooks/pre-applypatch.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed 4 | # by applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. 8 | # 9 | # To enable this hook, rename this file to "pre-applypatch". 10 | 11 | . git-sh-setup 12 | test -x "$GIT_DIR/hooks/pre-commit" && 13 | exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} 14 | : 15 | -------------------------------------------------------------------------------- /test/fixtures/simple/hooks/pre-applypatch.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed 4 | # by applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. 8 | # 9 | # To enable this hook, rename this file to "pre-applypatch". 10 | 11 | . git-sh-setup 12 | test -x "$GIT_DIR/hooks/pre-commit" && 13 | exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} 14 | : 15 | -------------------------------------------------------------------------------- /test/fixtures/status/hooks/pre-applypatch.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed 4 | # by applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. 8 | # 9 | # To enable this hook, rename this file to "pre-applypatch". 10 | 11 | . git-sh-setup 12 | test -x "$GIT_DIR/hooks/pre-commit" && 13 | exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} 14 | : 15 | -------------------------------------------------------------------------------- /test/fixtures/tagged/hooks/pre-applypatch.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed 4 | # by applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. 8 | # 9 | # To enable this hook, rename this file to "pre-applypatch". 10 | 11 | . git-sh-setup 12 | test -x "$GIT_DIR/hooks/pre-commit" && 13 | exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} 14 | : 15 | -------------------------------------------------------------------------------- /test/fixtures/branched/hooks/pre-applypatch.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed 4 | # by applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. 8 | # 9 | # To enable this hook, rename this file to "pre-applypatch". 10 | 11 | . git-sh-setup 12 | test -x "$GIT_DIR/hooks/pre-commit" && 13 | exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} 14 | : 15 | -------------------------------------------------------------------------------- /test/fixtures/checkout/hooks/pre-applypatch.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed 4 | # by applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. 8 | # 9 | # To enable this hook, rename this file to "pre-applypatch". 10 | 11 | . git-sh-setup 12 | test -x "$GIT_DIR/hooks/pre-commit" && 13 | exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} 14 | : 15 | -------------------------------------------------------------------------------- /test/fixtures/no_branch/hooks/pre-applypatch.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed 4 | # by applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. 8 | # 9 | # To enable this hook, rename this file to "pre-applypatch". 10 | 11 | . git-sh-setup 12 | test -x "$GIT_DIR/hooks/pre-commit" && 13 | exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} 14 | : 15 | -------------------------------------------------------------------------------- /test/fixtures/status_opts/hooks/pre-applypatch.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed 4 | # by applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. 8 | # 9 | # To enable this hook, rename this file to "pre-applypatch". 10 | 11 | . git-sh-setup 12 | test -x "$GIT_DIR/hooks/pre-commit" && 13 | exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} 14 | : 15 | -------------------------------------------------------------------------------- /test/fixtures/submodule/hooks/pre-applypatch.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed 4 | # by applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. 8 | # 9 | # To enable this hook, rename this file to "pre-applypatch". 10 | 11 | . git-sh-setup 12 | test -x "$GIT_DIR/hooks/pre-commit" && 13 | exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} 14 | : 15 | -------------------------------------------------------------------------------- /test/fixtures.coffee: -------------------------------------------------------------------------------- 1 | git = require '../src' 2 | 3 | dir = "#{__dirname}/fixtures" 4 | 5 | module.exports = 6 | branched: git("#{dir}/branched", true) 7 | checkout: git("#{dir}/checkout", true) 8 | gpgsigned: git("#{dir}/gpgsigned", true) 9 | remotes: git("#{dir}/remotes", true) 10 | simple: git("#{dir}/simple", true) 11 | status: git("#{dir}/status", true) 12 | submodule: git("#{dir}/submodule", true) 13 | tagged: git("#{dir}/tagged", true) 14 | noBranch: git("#{dir}/no_branch", true) 15 | -------------------------------------------------------------------------------- /src/config.coffee: -------------------------------------------------------------------------------- 1 | module.exports = C = (repo, callback) -> 2 | repo.git "config", {list: true}, (err, stdout, stderr) -> 3 | config = new Config repo 4 | config.parse stdout 5 | callback err, config 6 | 7 | C.Config = class Config 8 | constructor: (@repo) -> 9 | 10 | # Internal: Parse the config from stdout of a `git config` command 11 | parse: (text)-> 12 | @items = {} 13 | for line in text.split("\n") 14 | if line.length == 0 15 | continue 16 | [key, value] = line.split('=') 17 | @items[key] = value 18 | -------------------------------------------------------------------------------- /test/fixtures/branched/hooks/applypatch-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message taken by 4 | # applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. The hook is 8 | # allowed to edit the commit message file. 9 | # 10 | # To enable this hook, rename this file to "applypatch-msg". 11 | 12 | . git-sh-setup 13 | test -x "$GIT_DIR/hooks/commit-msg" && 14 | exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} 15 | : 16 | -------------------------------------------------------------------------------- /test/fixtures/checkout/hooks/applypatch-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message taken by 4 | # applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. The hook is 8 | # allowed to edit the commit message file. 9 | # 10 | # To enable this hook, rename this file to "applypatch-msg". 11 | 12 | . git-sh-setup 13 | test -x "$GIT_DIR/hooks/commit-msg" && 14 | exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} 15 | : 16 | -------------------------------------------------------------------------------- /test/fixtures/remotes/hooks/applypatch-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message taken by 4 | # applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. The hook is 8 | # allowed to edit the commit message file. 9 | # 10 | # To enable this hook, rename this file to "applypatch-msg". 11 | 12 | . git-sh-setup 13 | test -x "$GIT_DIR/hooks/commit-msg" && 14 | exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} 15 | : 16 | -------------------------------------------------------------------------------- /test/fixtures/simple/hooks/applypatch-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message taken by 4 | # applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. The hook is 8 | # allowed to edit the commit message file. 9 | # 10 | # To enable this hook, rename this file to "applypatch-msg". 11 | 12 | . git-sh-setup 13 | test -x "$GIT_DIR/hooks/commit-msg" && 14 | exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} 15 | : 16 | -------------------------------------------------------------------------------- /test/fixtures/status/hooks/applypatch-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message taken by 4 | # applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. The hook is 8 | # allowed to edit the commit message file. 9 | # 10 | # To enable this hook, rename this file to "applypatch-msg". 11 | 12 | . git-sh-setup 13 | test -x "$GIT_DIR/hooks/commit-msg" && 14 | exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} 15 | : 16 | -------------------------------------------------------------------------------- /test/fixtures/tagged/hooks/applypatch-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message taken by 4 | # applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. The hook is 8 | # allowed to edit the commit message file. 9 | # 10 | # To enable this hook, rename this file to "applypatch-msg". 11 | 12 | . git-sh-setup 13 | test -x "$GIT_DIR/hooks/commit-msg" && 14 | exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} 15 | : 16 | -------------------------------------------------------------------------------- /test/fixtures/clean/a.coffee: -------------------------------------------------------------------------------- 1 | # Assignment: 2 | number = 42 3 | opposite = true 4 | 5 | # Conditions: 6 | number = -42 if opposite 7 | 8 | # Functions: 9 | square = (x) -> x * x 10 | 11 | # Arrays: 12 | list = [1, 2, 3, 4, 5] 13 | 14 | # Objects: 15 | math = 16 | root: Math.sqrt 17 | square: square 18 | cube: (x) -> x * square x 19 | 20 | # Splats: 21 | race = (winner, runners...) -> 22 | print winner, runners 23 | 24 | # Existence: 25 | alert "I knew it!" if elvis? 26 | 27 | # Array comprehensions: 28 | cubes = (math.cube num for num in list) 29 | -------------------------------------------------------------------------------- /test/fixtures/no_branch/hooks/applypatch-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message taken by 4 | # applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. The hook is 8 | # allowed to edit the commit message file. 9 | # 10 | # To enable this hook, rename this file to "applypatch-msg". 11 | 12 | . git-sh-setup 13 | test -x "$GIT_DIR/hooks/commit-msg" && 14 | exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} 15 | : 16 | -------------------------------------------------------------------------------- /test/fixtures/reset/a.coffee: -------------------------------------------------------------------------------- 1 | # Assignment: 2 | number = 42 3 | opposite = true 4 | 5 | # Conditions: 6 | number = -42 if opposite 7 | 8 | # Functions: 9 | square = (x) -> x * x 10 | 11 | # Arrays: 12 | list = [1, 2, 3, 4, 5] 13 | 14 | # Objects: 15 | math = 16 | root: Math.sqrt 17 | square: square 18 | cube: (x) -> x * square x 19 | 20 | # Splats: 21 | race = (winner, runners...) -> 22 | print winner, runners 23 | 24 | # Existence: 25 | alert "I knew it!" if elvis? 26 | 27 | # Array comprehensions: 28 | cubes = (math.cube num for num in list) 29 | -------------------------------------------------------------------------------- /test/fixtures/status_opts/hooks/applypatch-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message taken by 4 | # applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. The hook is 8 | # allowed to edit the commit message file. 9 | # 10 | # To enable this hook, rename this file to "applypatch-msg". 11 | 12 | . git-sh-setup 13 | test -x "$GIT_DIR/hooks/commit-msg" && 14 | exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} 15 | : 16 | -------------------------------------------------------------------------------- /test/fixtures/submodule/hooks/applypatch-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message taken by 4 | # applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. The hook is 8 | # allowed to edit the commit message file. 9 | # 10 | # To enable this hook, rename this file to "applypatch-msg". 11 | 12 | . git-sh-setup 13 | test -x "$GIT_DIR/hooks/commit-msg" && 14 | exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} 15 | : 16 | -------------------------------------------------------------------------------- /src/actor.coffee: -------------------------------------------------------------------------------- 1 | crypto = require 'crypto' 2 | 3 | module.exports = class Actor 4 | constructor: (@name, @email) -> 5 | if @email 6 | @hash = crypto.createHash("md5").update(@email, "ascii").digest("hex") 7 | 8 | # Public: Get a string representation of the Actor. 9 | toString: -> 10 | "#{@name} <#{@email}>" 11 | 12 | # Public: Parse an Actor from a "bla " string. 13 | # 14 | # Returns Actor. 15 | @from_string: (str) -> 16 | if /<.+>/.test str 17 | [m, name, email] = /(.*) <(.+?)>/.exec str 18 | return new Actor(name, email) 19 | else 20 | return new Actor(str, null) 21 | -------------------------------------------------------------------------------- /test/fixtures/branched/hooks/post-receive.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script for the "post-receive" event. 4 | # 5 | # The "post-receive" script is run after receive-pack has accepted a pack 6 | # and the repository has been updated. It is passed arguments in through 7 | # stdin in the form 8 | # 9 | # For example: 10 | # aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master 11 | # 12 | # see contrib/hooks/ for a sample, or uncomment the next line and 13 | # rename the file to "post-receive". 14 | 15 | #. /usr/share/doc/git-core/contrib/hooks/post-receive-email 16 | -------------------------------------------------------------------------------- /test/fixtures/checkout/hooks/post-receive.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script for the "post-receive" event. 4 | # 5 | # The "post-receive" script is run after receive-pack has accepted a pack 6 | # and the repository has been updated. It is passed arguments in through 7 | # stdin in the form 8 | # 9 | # For example: 10 | # aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master 11 | # 12 | # see contrib/hooks/ for a sample, or uncomment the next line and 13 | # rename the file to "post-receive". 14 | 15 | #. /usr/share/doc/git-core/contrib/hooks/post-receive-email 16 | -------------------------------------------------------------------------------- /test/fixtures/remotes/hooks/post-receive.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script for the "post-receive" event. 4 | # 5 | # The "post-receive" script is run after receive-pack has accepted a pack 6 | # and the repository has been updated. It is passed arguments in through 7 | # stdin in the form 8 | # 9 | # For example: 10 | # aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master 11 | # 12 | # see contrib/hooks/ for a sample, or uncomment the next line and 13 | # rename the file to "post-receive". 14 | 15 | #. /usr/share/doc/git-core/contrib/hooks/post-receive-email 16 | -------------------------------------------------------------------------------- /test/fixtures/simple/hooks/post-receive.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script for the "post-receive" event. 4 | # 5 | # The "post-receive" script is run after receive-pack has accepted a pack 6 | # and the repository has been updated. It is passed arguments in through 7 | # stdin in the form 8 | # 9 | # For example: 10 | # aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master 11 | # 12 | # see contrib/hooks/ for a sample, or uncomment the next line and 13 | # rename the file to "post-receive". 14 | 15 | #. /usr/share/doc/git-core/contrib/hooks/post-receive-email 16 | -------------------------------------------------------------------------------- /test/fixtures/status/hooks/post-receive.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script for the "post-receive" event. 4 | # 5 | # The "post-receive" script is run after receive-pack has accepted a pack 6 | # and the repository has been updated. It is passed arguments in through 7 | # stdin in the form 8 | # 9 | # For example: 10 | # aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master 11 | # 12 | # see contrib/hooks/ for a sample, or uncomment the next line and 13 | # rename the file to "post-receive". 14 | 15 | #. /usr/share/doc/git-core/contrib/hooks/post-receive-email 16 | -------------------------------------------------------------------------------- /test/fixtures/submodule/hooks/post-receive.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script for the "post-receive" event. 4 | # 5 | # The "post-receive" script is run after receive-pack has accepted a pack 6 | # and the repository has been updated. It is passed arguments in through 7 | # stdin in the form 8 | # 9 | # For example: 10 | # aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master 11 | # 12 | # see contrib/hooks/ for a sample, or uncomment the next line and 13 | # rename the file to "post-receive". 14 | 15 | #. /usr/share/doc/git-core/contrib/hooks/post-receive-email 16 | -------------------------------------------------------------------------------- /test/fixtures/tagged/hooks/post-receive.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script for the "post-receive" event. 4 | # 5 | # The "post-receive" script is run after receive-pack has accepted a pack 6 | # and the repository has been updated. It is passed arguments in through 7 | # stdin in the form 8 | # 9 | # For example: 10 | # aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master 11 | # 12 | # see contrib/hooks/ for a sample, or uncomment the next line and 13 | # rename the file to "post-receive". 14 | 15 | #. /usr/share/doc/git-core/contrib/hooks/post-receive-email 16 | -------------------------------------------------------------------------------- /test/fixtures/status_opts/hooks/post-receive.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script for the "post-receive" event. 4 | # 5 | # The "post-receive" script is run after receive-pack has accepted a pack 6 | # and the repository has been updated. It is passed arguments in through 7 | # stdin in the form 8 | # 9 | # For example: 10 | # aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master 11 | # 12 | # see contrib/hooks/ for a sample, or uncomment the next line and 13 | # rename the file to "post-receive". 14 | 15 | #. /usr/share/doc/git-core/contrib/hooks/post-receive-email 16 | -------------------------------------------------------------------------------- /test/fixtures/status_opts/npm-debug.log: -------------------------------------------------------------------------------- 1 | 0 info it worked if it ends with ok 2 | 1 verbose cli [ 'node', '/usr/local/bin/npm', 'test' ] 3 | 2 info using npm@1.4.23 4 | 3 info using node@v0.10.31 5 | 4 error Error: ENOENT, open '/Users/dbond/src/gift/test/fixtures/status_opts/package.json' 6 | 5 error If you need help, you may report this *entire* log, 7 | 5 error including the npm and node versions, at: 8 | 5 error 9 | 6 error System Darwin 12.5.0 10 | 7 error command "node" "/usr/local/bin/npm" "test" 11 | 8 error cwd /Users/dbond/src/gift/test/fixtures/status_opts 12 | 9 error node -v v0.10.31 13 | 10 error npm -v 1.4.23 14 | 11 error path /Users/dbond/src/gift/test/fixtures/status_opts/package.json 15 | 12 error code ENOENT 16 | 13 error errno 34 17 | 14 verbose exit [ 34, true ] 18 | -------------------------------------------------------------------------------- /src/status.coffee: -------------------------------------------------------------------------------- 1 | # Public: Create a Status. 2 | # 3 | # repo - A Repo. 4 | # callback - Receives `(err, status)` 5 | # 6 | module.exports = S = (repo, options, callback) -> 7 | repo.git "status --porcelain", options, (err, stdout, stderr) -> 8 | status = new Status repo 9 | status.parse stdout 10 | return callback err, status 11 | 12 | S.Status = class Status 13 | constructor: (@repo) -> 14 | 15 | # Internal: Parse the status from stdout of a `git status` command. 16 | parse: (text) -> 17 | @files = {} 18 | @clean = text.length == 0 19 | for line in text.split("\n") 20 | if line.length == 0 21 | continue 22 | file = line.substr 3 23 | type = line.substr 0,2 24 | @files[file] = { staged: (line[0] != " " and line[0] != "?" ) , tracked: line[0] != "?" } 25 | if type != "??" 26 | @files[file].type = type.trim() 27 | -------------------------------------------------------------------------------- /test/fixtures/tagged/logs/HEAD: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 91d6d39cd8638f1067989e0ab9c9c00ca378c952 sentientwaffle 1329090329 -0700 commit (initial): commit 1 2 | 91d6d39cd8638f1067989e0ab9c9c00ca378c952 ebcbdf47e0ad6503d09f59cd8eeb76d9435a0396 sentientwaffle 1329090345 -0700 commit: commit 2 3 | ebcbdf47e0ad6503d09f59cd8eeb76d9435a0396 ea1658a2ba3f3c4f9f50fa19765ba7d0b5dcd27c sentientwaffle 1329090351 -0700 commit: commit 3 4 | ea1658a2ba3f3c4f9f50fa19765ba7d0b5dcd27c bbfb0e8e077ab9b37941097883f4e917ecca3d33 sentientwaffle 1329090358 -0700 commit: commit 4 5 | bbfb0e8e077ab9b37941097883f4e917ecca3d33 32bbb351de16c3e404b3b7c77601c3d124e1e1a1 sentientwaffle 1329090365 -0700 commit: commit 5 6 | 32bbb351de16c3e404b3b7c77601c3d124e1e1a1 78cb34985ee281f9b8008b556ad5b4dd36473b10 sentientwaffle 1329090407 -0700 commit: commit 6 7 | -------------------------------------------------------------------------------- /test/fixtures/clean/d.js: -------------------------------------------------------------------------------- 1 | var cubes, list, math, num, number, opposite, race, square, 2 | __slice = [].slice; 3 | 4 | number = 42; 5 | 6 | opposite = true; 7 | 8 | if (opposite) { 9 | number = -42; 10 | } 11 | 12 | square = function(x) { 13 | return x * x; 14 | }; 15 | 16 | list = [1, 2, 3, 4, 5]; 17 | 18 | math = { 19 | root: Math.sqrt, 20 | square: square, 21 | cube: function(x) { 22 | return x * square(x); 23 | } 24 | }; 25 | 26 | race = function() { 27 | var runners, winner; 28 | winner = arguments[0], runners = 2 <= arguments.length ? __slice.call(arguments, 1) : []; 29 | return print(winner, runners); 30 | }; 31 | 32 | if (typeof elvis !== "undefined" && elvis !== null) { 33 | alert("I knew it!"); 34 | } 35 | 36 | cubes = (function() { 37 | var _i, _len, _results; 38 | _results = []; 39 | for (_i = 0, _len = list.length; _i < _len; _i++) { 40 | num = list[_i]; 41 | _results.push(math.cube(num)); 42 | } 43 | return _results; 44 | })(); 45 | -------------------------------------------------------------------------------- /test/fixtures/reset/d.js: -------------------------------------------------------------------------------- 1 | var cubes, list, math, num, number, opposite, race, square, 2 | __slice = [].slice; 3 | 4 | number = 42; 5 | 6 | opposite = true; 7 | 8 | if (opposite) { 9 | number = -42; 10 | } 11 | 12 | square = function(x) { 13 | return x * x; 14 | }; 15 | 16 | list = [1, 2, 3, 4, 5]; 17 | 18 | math = { 19 | root: Math.sqrt, 20 | square: square, 21 | cube: function(x) { 22 | return x * square(x); 23 | } 24 | }; 25 | 26 | race = function() { 27 | var runners, winner; 28 | winner = arguments[0], runners = 2 <= arguments.length ? __slice.call(arguments, 1) : []; 29 | return print(winner, runners); 30 | }; 31 | 32 | if (typeof elvis !== "undefined" && elvis !== null) { 33 | alert("I knew it!"); 34 | } 35 | 36 | cubes = (function() { 37 | var _i, _len, _results; 38 | _results = []; 39 | for (_i = 0, _len = list.length; _i < _len; _i++) { 40 | num = list[_i]; 41 | _results.push(math.cube(num)); 42 | } 43 | return _results; 44 | })(); 45 | -------------------------------------------------------------------------------- /test/fixtures/tagged/logs/refs/heads/master: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 91d6d39cd8638f1067989e0ab9c9c00ca378c952 sentientwaffle 1329090329 -0700 commit (initial): commit 1 2 | 91d6d39cd8638f1067989e0ab9c9c00ca378c952 ebcbdf47e0ad6503d09f59cd8eeb76d9435a0396 sentientwaffle 1329090345 -0700 commit: commit 2 3 | ebcbdf47e0ad6503d09f59cd8eeb76d9435a0396 ea1658a2ba3f3c4f9f50fa19765ba7d0b5dcd27c sentientwaffle 1329090351 -0700 commit: commit 3 4 | ea1658a2ba3f3c4f9f50fa19765ba7d0b5dcd27c bbfb0e8e077ab9b37941097883f4e917ecca3d33 sentientwaffle 1329090358 -0700 commit: commit 4 5 | bbfb0e8e077ab9b37941097883f4e917ecca3d33 32bbb351de16c3e404b3b7c77601c3d124e1e1a1 sentientwaffle 1329090365 -0700 commit: commit 5 6 | 32bbb351de16c3e404b3b7c77601c3d124e1e1a1 78cb34985ee281f9b8008b556ad5b4dd36473b10 sentientwaffle 1329090407 -0700 commit: commit 6 7 | -------------------------------------------------------------------------------- /src/blob.coffee: -------------------------------------------------------------------------------- 1 | path = require 'path' 2 | 3 | module.exports = class Blob 4 | constructor: (@repo, attrs) -> 5 | {@id, @name, @mode} = attrs 6 | 7 | # Public: Get the blob contents. 8 | # 9 | # callback - Receives `(err, data)`. 10 | # 11 | # Warning, this only returns files less than 200k, the standard buffer size for 12 | # node's exec(). If you need to get bigger files, you should use dataStream() to 13 | # get a stream for the file's data 14 | # 15 | data: (callback) -> 16 | @repo.git "cat-file", {p: true}, @id 17 | , (err, stdout, stderr) -> 18 | return callback err, stdout 19 | , 'binary' 20 | 21 | # Public: Get the blob contents as a stream 22 | # 23 | # returns - [dataStream, errstream] 24 | # 25 | # Usage: 26 | # [blobstream, _] = blob.dataStream() 27 | # blobstream.pipe(res) 28 | # 29 | dataStream: () -> 30 | streams = @repo.git.streamCmd "cat-file", {p: true}, [@id] 31 | return streams 32 | 33 | toString: -> 34 | "#" 35 | -------------------------------------------------------------------------------- /test/fixtures/branched/hooks/commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message. 4 | # Called by git-commit with one argument, the name of the file 5 | # that has the commit message. The hook should exit with non-zero 6 | # status after issuing an appropriate message if it wants to stop the 7 | # commit. The hook is allowed to edit the commit message file. 8 | # 9 | # To enable this hook, rename this file to "commit-msg". 10 | 11 | # Uncomment the below to add a Signed-off-by line to the message. 12 | # Doing this in a hook is a bad idea in general, but the prepare-commit-msg 13 | # hook is more suited to it. 14 | # 15 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 16 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 17 | 18 | # This example catches duplicate Signed-off-by lines. 19 | 20 | test "" = "$(grep '^Signed-off-by: ' "$1" | 21 | sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { 22 | echo >&2 Duplicate Signed-off-by lines. 23 | exit 1 24 | } 25 | -------------------------------------------------------------------------------- /test/fixtures/checkout/hooks/commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message. 4 | # Called by git-commit with one argument, the name of the file 5 | # that has the commit message. The hook should exit with non-zero 6 | # status after issuing an appropriate message if it wants to stop the 7 | # commit. The hook is allowed to edit the commit message file. 8 | # 9 | # To enable this hook, rename this file to "commit-msg". 10 | 11 | # Uncomment the below to add a Signed-off-by line to the message. 12 | # Doing this in a hook is a bad idea in general, but the prepare-commit-msg 13 | # hook is more suited to it. 14 | # 15 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 16 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 17 | 18 | # This example catches duplicate Signed-off-by lines. 19 | 20 | test "" = "$(grep '^Signed-off-by: ' "$1" | 21 | sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { 22 | echo >&2 Duplicate Signed-off-by lines. 23 | exit 1 24 | } 25 | -------------------------------------------------------------------------------- /test/fixtures/remotes/hooks/commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message. 4 | # Called by git-commit with one argument, the name of the file 5 | # that has the commit message. The hook should exit with non-zero 6 | # status after issuing an appropriate message if it wants to stop the 7 | # commit. The hook is allowed to edit the commit message file. 8 | # 9 | # To enable this hook, rename this file to "commit-msg". 10 | 11 | # Uncomment the below to add a Signed-off-by line to the message. 12 | # Doing this in a hook is a bad idea in general, but the prepare-commit-msg 13 | # hook is more suited to it. 14 | # 15 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 16 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 17 | 18 | # This example catches duplicate Signed-off-by lines. 19 | 20 | test "" = "$(grep '^Signed-off-by: ' "$1" | 21 | sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { 22 | echo >&2 Duplicate Signed-off-by lines. 23 | exit 1 24 | } 25 | -------------------------------------------------------------------------------- /test/fixtures/simple/hooks/commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message. 4 | # Called by git-commit with one argument, the name of the file 5 | # that has the commit message. The hook should exit with non-zero 6 | # status after issuing an appropriate message if it wants to stop the 7 | # commit. The hook is allowed to edit the commit message file. 8 | # 9 | # To enable this hook, rename this file to "commit-msg". 10 | 11 | # Uncomment the below to add a Signed-off-by line to the message. 12 | # Doing this in a hook is a bad idea in general, but the prepare-commit-msg 13 | # hook is more suited to it. 14 | # 15 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 16 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 17 | 18 | # This example catches duplicate Signed-off-by lines. 19 | 20 | test "" = "$(grep '^Signed-off-by: ' "$1" | 21 | sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { 22 | echo >&2 Duplicate Signed-off-by lines. 23 | exit 1 24 | } 25 | -------------------------------------------------------------------------------- /test/fixtures/status/hooks/commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message. 4 | # Called by git-commit with one argument, the name of the file 5 | # that has the commit message. The hook should exit with non-zero 6 | # status after issuing an appropriate message if it wants to stop the 7 | # commit. The hook is allowed to edit the commit message file. 8 | # 9 | # To enable this hook, rename this file to "commit-msg". 10 | 11 | # Uncomment the below to add a Signed-off-by line to the message. 12 | # Doing this in a hook is a bad idea in general, but the prepare-commit-msg 13 | # hook is more suited to it. 14 | # 15 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 16 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 17 | 18 | # This example catches duplicate Signed-off-by lines. 19 | 20 | test "" = "$(grep '^Signed-off-by: ' "$1" | 21 | sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { 22 | echo >&2 Duplicate Signed-off-by lines. 23 | exit 1 24 | } 25 | -------------------------------------------------------------------------------- /test/fixtures/submodule/hooks/commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message. 4 | # Called by git-commit with one argument, the name of the file 5 | # that has the commit message. The hook should exit with non-zero 6 | # status after issuing an appropriate message if it wants to stop the 7 | # commit. The hook is allowed to edit the commit message file. 8 | # 9 | # To enable this hook, rename this file to "commit-msg". 10 | 11 | # Uncomment the below to add a Signed-off-by line to the message. 12 | # Doing this in a hook is a bad idea in general, but the prepare-commit-msg 13 | # hook is more suited to it. 14 | # 15 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 16 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 17 | 18 | # This example catches duplicate Signed-off-by lines. 19 | 20 | test "" = "$(grep '^Signed-off-by: ' "$1" | 21 | sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { 22 | echo >&2 Duplicate Signed-off-by lines. 23 | exit 1 24 | } 25 | -------------------------------------------------------------------------------- /test/fixtures/tagged/hooks/commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message. 4 | # Called by git-commit with one argument, the name of the file 5 | # that has the commit message. The hook should exit with non-zero 6 | # status after issuing an appropriate message if it wants to stop the 7 | # commit. The hook is allowed to edit the commit message file. 8 | # 9 | # To enable this hook, rename this file to "commit-msg". 10 | 11 | # Uncomment the below to add a Signed-off-by line to the message. 12 | # Doing this in a hook is a bad idea in general, but the prepare-commit-msg 13 | # hook is more suited to it. 14 | # 15 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 16 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 17 | 18 | # This example catches duplicate Signed-off-by lines. 19 | 20 | test "" = "$(grep '^Signed-off-by: ' "$1" | 21 | sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { 22 | echo >&2 Duplicate Signed-off-by lines. 23 | exit 1 24 | } 25 | -------------------------------------------------------------------------------- /test/fixtures/no_branch/hooks/commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message. 4 | # Called by "git commit" with one argument, the name of the file 5 | # that has the commit message. The hook should exit with non-zero 6 | # status after issuing an appropriate message if it wants to stop the 7 | # commit. The hook is allowed to edit the commit message file. 8 | # 9 | # To enable this hook, rename this file to "commit-msg". 10 | 11 | # Uncomment the below to add a Signed-off-by line to the message. 12 | # Doing this in a hook is a bad idea in general, but the prepare-commit-msg 13 | # hook is more suited to it. 14 | # 15 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 16 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 17 | 18 | # This example catches duplicate Signed-off-by lines. 19 | 20 | test "" = "$(grep '^Signed-off-by: ' "$1" | 21 | sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { 22 | echo >&2 Duplicate Signed-off-by lines. 23 | exit 1 24 | } 25 | -------------------------------------------------------------------------------- /test/fixtures/status_opts/hooks/commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message. 4 | # Called by git-commit with one argument, the name of the file 5 | # that has the commit message. The hook should exit with non-zero 6 | # status after issuing an appropriate message if it wants to stop the 7 | # commit. The hook is allowed to edit the commit message file. 8 | # 9 | # To enable this hook, rename this file to "commit-msg". 10 | 11 | # Uncomment the below to add a Signed-off-by line to the message. 12 | # Doing this in a hook is a bad idea in general, but the prepare-commit-msg 13 | # hook is more suited to it. 14 | # 15 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 16 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 17 | 18 | # This example catches duplicate Signed-off-by lines. 19 | 20 | test "" = "$(grep '^Signed-off-by: ' "$1" | 21 | sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { 22 | echo >&2 Duplicate Signed-off-by lines. 23 | exit 1 24 | } 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gift", 3 | "version": "0.10.2", 4 | "description": "a Git wrapper library", 5 | "keywords": [ 6 | "git", 7 | "cli", 8 | "wrapper" 9 | ], 10 | "homepage": "https://github.com/notatestuser/gift", 11 | "bugs": { 12 | "url": "https://github.com/notatestuser/gift/issues" 13 | }, 14 | "author": { 15 | "name": "sentientwaffle", 16 | "url": "http://sentientwaffle.github.com/" 17 | }, 18 | "license": "MIT", 19 | "main": "./lib/index", 20 | "scripts": { 21 | "test": "mocha --compilers coffee:\"./node_modules/coffee-script/lib/coffee-script/register\"", 22 | "prepublish": "coffee -o lib -c src" 23 | }, 24 | "repository": { 25 | "type": "git", 26 | "url": "https://github.com/notatestuser/gift.git" 27 | }, 28 | "dependencies": { 29 | "flex-exec": "^1.0.0", 30 | "underscore": "^1.8.3" 31 | }, 32 | "devDependencies": { 33 | "coffee-script": "^1.12.7", 34 | "fs-extra": "^4.0.2", 35 | "mocha": "^10.2.0", 36 | "should": "^13.1.3", 37 | "sinon": "^4.1.1" 38 | }, 39 | "engines": { 40 | "node": ">=4" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 [DJG](https://github.com/sentientwaffle) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files 5 | (the "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject 9 | to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included 12 | in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /test/config.test.coffee: -------------------------------------------------------------------------------- 1 | should = require 'should' 2 | Config = require '../src/config' 3 | 4 | GIT_CONFIG = """ 5 | user.name=John Doe 6 | user.email=john.doe@git-scm.com 7 | core.editor=pico 8 | """ 9 | 10 | GIT_CONFIG_DUPLICATE_KEYS = """ 11 | user.name=John Doe 12 | user.email=john.doe@git-scm.com 13 | core.editor=pico 14 | user.email=john.doe@github.com 15 | core.editor=emacs 16 | """ 17 | 18 | describe "Config", -> 19 | describe "()", -> 20 | describe "when there are no overlapping keys", -> 21 | config = new Config.Config 'mock repo' 22 | config.parse GIT_CONFIG 23 | 24 | it "read the keys and values", -> 25 | config.items['user.name'].should.equal 'John Doe' 26 | config.items['user.email'].should.equal 'john.doe@git-scm.com' 27 | config.items['core.editor'].should.equal 'pico' 28 | 29 | describe "with overlapping keys", -> 30 | config = new Config.Config 'mock repo' 31 | config.parse GIT_CONFIG_DUPLICATE_KEYS 32 | 33 | it "read the keys and values", -> 34 | config.items['user.name'].should.equal 'John Doe' 35 | config.items['user.email'].should.equal 'john.doe@github.com' 36 | config.items['core.editor'].should.equal 'emacs' 37 | -------------------------------------------------------------------------------- /test/fixtures/branched/logs/HEAD: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 b045ec4b14c60f03329654266478b6e8b92b33c5 sentientwaffle 1328999490 -0700 commit (initial): 1 2 | b045ec4b14c60f03329654266478b6e8b92b33c5 b045ec4b14c60f03329654266478b6e8b92b33c5 sentientwaffle 1328999503 -0700 checkout: moving from master to something 3 | b045ec4b14c60f03329654266478b6e8b92b33c5 7783d64e077617ab7b84fe9726f721e921b9623b sentientwaffle 1328999518 -0700 commit: 2 4 | 7783d64e077617ab7b84fe9726f721e921b9623b b045ec4b14c60f03329654266478b6e8b92b33c5 sentientwaffle 1328999521 -0700 checkout: moving from something to master 5 | b045ec4b14c60f03329654266478b6e8b92b33c5 7783d64e077617ab7b84fe9726f721e921b9623b sentientwaffle 1329001555 -0700 checkout: moving from master to something 6 | 7783d64e077617ab7b84fe9726f721e921b9623b b045ec4b14c60f03329654266478b6e8b92b33c5 sentientwaffle 1329013635 -0700 checkout: moving from something to master 7 | b045ec4b14c60f03329654266478b6e8b92b33c5 913318e66e9beed3e89e9c402c1d6585ef3f7e6f sentientwaffle 1329013671 -0700 commit: add a sub dir 8 | -------------------------------------------------------------------------------- /test/tag.test.coffee: -------------------------------------------------------------------------------- 1 | should = require 'should' 2 | fixtures = require './fixtures' 3 | git = require '../src' 4 | Tag = require '../src/tag' 5 | 6 | describe "Tag", -> 7 | describe ".find_all", -> 8 | repo = fixtures.tagged 9 | tags = null 10 | before (done) -> 11 | Tag.find_all repo, (err, _tags) -> 12 | tags = _tags 13 | done err 14 | 15 | it "is an Array of Tags", -> 16 | tags.should.be.an.instanceof Array 17 | tags[0].should.be.an.instanceof Tag 18 | 19 | pref = "the tag" 20 | it "#{pref} has the correct name", -> 21 | tags[0].name.should.eql "tag-1" 22 | 23 | it "#{pref} has the correct commit", -> 24 | tags[0].commit.id.should.eql "32bbb351de16c3e404b3b7c77601c3d124e1e1a1" 25 | 26 | 27 | describe "#message", -> 28 | repo = fixtures.tagged 29 | tags = null 30 | message = null 31 | before (done) -> 32 | repo.tags (err, _tags) -> 33 | tags = _tags 34 | done err if err 35 | tags[0].message (err, _message) -> 36 | message = _message 37 | done err 38 | 39 | it "is the correct message", -> 40 | message.should.containEql "the first tag" 41 | 42 | it "has the correct commit", -> 43 | tags[0].commit.message.should.eql "commit 5" 44 | 45 | -------------------------------------------------------------------------------- /test/actor.test.coffee: -------------------------------------------------------------------------------- 1 | should = require 'should' 2 | Actor = require '../src/actor' 3 | 4 | describe "Actor", -> 5 | describe ".constructor", -> 6 | actor = new Actor "bob", "bob@example.com" 7 | it "assigns @name", -> 8 | actor.name.should.eql "bob" 9 | 10 | it "assigns @email", -> 11 | actor.email.should.eql "bob@example.com" 12 | 13 | 14 | describe "#toString", -> 15 | actor = new Actor "bob", "bob@example.com" 16 | 17 | it "is a string representation of the actor", -> 18 | actor.toString().should.eql "bob " 19 | 20 | 21 | describe "#hash", -> 22 | actor = new Actor "bob", "bob@example.com" 23 | 24 | it "is the md5 hash of the email", -> 25 | actor.hash.should.eql "4b9bb80620f03eb3719e0a061c14283d" 26 | 27 | 28 | describe ".from_string", -> 29 | describe "with a name and email", -> 30 | actor = Actor.from_string "bob " 31 | it "parses the name", -> 32 | actor.name.should.eql "bob" 33 | 34 | it "parses the email", -> 35 | actor.email.should.eql "bob@example.com" 36 | 37 | describe "with only a name", -> 38 | actor = Actor.from_string "bob" 39 | it "parses the name", -> 40 | actor.name.should.eql "bob" 41 | 42 | it "does not parse the email", -> 43 | should.not.exist actor.email 44 | -------------------------------------------------------------------------------- /test/fixtures/remotes/hooks/prepare-commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare the commit log message. 4 | # Called by git-commit with the name of the file that has the 5 | # commit message, followed by the description of the commit 6 | # message's source. The hook's purpose is to edit the commit 7 | # message file. If the hook fails with a non-zero status, 8 | # the commit is aborted. 9 | # 10 | # To enable this hook, rename this file to "prepare-commit-msg". 11 | 12 | # This hook includes three examples. The first comments out the 13 | # "Conflicts:" part of a merge commit. 14 | # 15 | # The second includes the output of "git diff --name-status -r" 16 | # into the message, just before the "git status" output. It is 17 | # commented because it doesn't cope with --amend or with squashed 18 | # commits. 19 | # 20 | # The third example adds a Signed-off-by line to the message, that can 21 | # still be edited. This is rarely a good idea. 22 | 23 | case "$2,$3" in 24 | merge,) 25 | perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; 26 | 27 | # ,|template,) 28 | # perl -i.bak -pe ' 29 | # print "\n" . `git diff --cached --name-status -r` 30 | # if /^#/ && $first++ == 0' "$1" ;; 31 | 32 | *) ;; 33 | esac 34 | 35 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 36 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 37 | -------------------------------------------------------------------------------- /test/fixtures/simple/hooks/prepare-commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare the commit log message. 4 | # Called by git-commit with the name of the file that has the 5 | # commit message, followed by the description of the commit 6 | # message's source. The hook's purpose is to edit the commit 7 | # message file. If the hook fails with a non-zero status, 8 | # the commit is aborted. 9 | # 10 | # To enable this hook, rename this file to "prepare-commit-msg". 11 | 12 | # This hook includes three examples. The first comments out the 13 | # "Conflicts:" part of a merge commit. 14 | # 15 | # The second includes the output of "git diff --name-status -r" 16 | # into the message, just before the "git status" output. It is 17 | # commented because it doesn't cope with --amend or with squashed 18 | # commits. 19 | # 20 | # The third example adds a Signed-off-by line to the message, that can 21 | # still be edited. This is rarely a good idea. 22 | 23 | case "$2,$3" in 24 | merge,) 25 | perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; 26 | 27 | # ,|template,) 28 | # perl -i.bak -pe ' 29 | # print "\n" . `git diff --cached --name-status -r` 30 | # if /^#/ && $first++ == 0' "$1" ;; 31 | 32 | *) ;; 33 | esac 34 | 35 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 36 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 37 | -------------------------------------------------------------------------------- /test/fixtures/status/hooks/prepare-commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare the commit log message. 4 | # Called by git-commit with the name of the file that has the 5 | # commit message, followed by the description of the commit 6 | # message's source. The hook's purpose is to edit the commit 7 | # message file. If the hook fails with a non-zero status, 8 | # the commit is aborted. 9 | # 10 | # To enable this hook, rename this file to "prepare-commit-msg". 11 | 12 | # This hook includes three examples. The first comments out the 13 | # "Conflicts:" part of a merge commit. 14 | # 15 | # The second includes the output of "git diff --name-status -r" 16 | # into the message, just before the "git status" output. It is 17 | # commented because it doesn't cope with --amend or with squashed 18 | # commits. 19 | # 20 | # The third example adds a Signed-off-by line to the message, that can 21 | # still be edited. This is rarely a good idea. 22 | 23 | case "$2,$3" in 24 | merge,) 25 | perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; 26 | 27 | # ,|template,) 28 | # perl -i.bak -pe ' 29 | # print "\n" . `git diff --cached --name-status -r` 30 | # if /^#/ && $first++ == 0' "$1" ;; 31 | 32 | *) ;; 33 | esac 34 | 35 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 36 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 37 | -------------------------------------------------------------------------------- /test/fixtures/tagged/hooks/prepare-commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare the commit log message. 4 | # Called by git-commit with the name of the file that has the 5 | # commit message, followed by the description of the commit 6 | # message's source. The hook's purpose is to edit the commit 7 | # message file. If the hook fails with a non-zero status, 8 | # the commit is aborted. 9 | # 10 | # To enable this hook, rename this file to "prepare-commit-msg". 11 | 12 | # This hook includes three examples. The first comments out the 13 | # "Conflicts:" part of a merge commit. 14 | # 15 | # The second includes the output of "git diff --name-status -r" 16 | # into the message, just before the "git status" output. It is 17 | # commented because it doesn't cope with --amend or with squashed 18 | # commits. 19 | # 20 | # The third example adds a Signed-off-by line to the message, that can 21 | # still be edited. This is rarely a good idea. 22 | 23 | case "$2,$3" in 24 | merge,) 25 | perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; 26 | 27 | # ,|template,) 28 | # perl -i.bak -pe ' 29 | # print "\n" . `git diff --cached --name-status -r` 30 | # if /^#/ && $first++ == 0' "$1" ;; 31 | 32 | *) ;; 33 | esac 34 | 35 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 36 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 37 | -------------------------------------------------------------------------------- /test/fixtures/branched/hooks/prepare-commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare the commit log message. 4 | # Called by git-commit with the name of the file that has the 5 | # commit message, followed by the description of the commit 6 | # message's source. The hook's purpose is to edit the commit 7 | # message file. If the hook fails with a non-zero status, 8 | # the commit is aborted. 9 | # 10 | # To enable this hook, rename this file to "prepare-commit-msg". 11 | 12 | # This hook includes three examples. The first comments out the 13 | # "Conflicts:" part of a merge commit. 14 | # 15 | # The second includes the output of "git diff --name-status -r" 16 | # into the message, just before the "git status" output. It is 17 | # commented because it doesn't cope with --amend or with squashed 18 | # commits. 19 | # 20 | # The third example adds a Signed-off-by line to the message, that can 21 | # still be edited. This is rarely a good idea. 22 | 23 | case "$2,$3" in 24 | merge,) 25 | perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; 26 | 27 | # ,|template,) 28 | # perl -i.bak -pe ' 29 | # print "\n" . `git diff --cached --name-status -r` 30 | # if /^#/ && $first++ == 0' "$1" ;; 31 | 32 | *) ;; 33 | esac 34 | 35 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 36 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 37 | -------------------------------------------------------------------------------- /test/fixtures/checkout/hooks/prepare-commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare the commit log message. 4 | # Called by git-commit with the name of the file that has the 5 | # commit message, followed by the description of the commit 6 | # message's source. The hook's purpose is to edit the commit 7 | # message file. If the hook fails with a non-zero status, 8 | # the commit is aborted. 9 | # 10 | # To enable this hook, rename this file to "prepare-commit-msg". 11 | 12 | # This hook includes three examples. The first comments out the 13 | # "Conflicts:" part of a merge commit. 14 | # 15 | # The second includes the output of "git diff --name-status -r" 16 | # into the message, just before the "git status" output. It is 17 | # commented because it doesn't cope with --amend or with squashed 18 | # commits. 19 | # 20 | # The third example adds a Signed-off-by line to the message, that can 21 | # still be edited. This is rarely a good idea. 22 | 23 | case "$2,$3" in 24 | merge,) 25 | perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; 26 | 27 | # ,|template,) 28 | # perl -i.bak -pe ' 29 | # print "\n" . `git diff --cached --name-status -r` 30 | # if /^#/ && $first++ == 0' "$1" ;; 31 | 32 | *) ;; 33 | esac 34 | 35 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 36 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 37 | -------------------------------------------------------------------------------- /test/fixtures/status_opts/hooks/prepare-commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare the commit log message. 4 | # Called by git-commit with the name of the file that has the 5 | # commit message, followed by the description of the commit 6 | # message's source. The hook's purpose is to edit the commit 7 | # message file. If the hook fails with a non-zero status, 8 | # the commit is aborted. 9 | # 10 | # To enable this hook, rename this file to "prepare-commit-msg". 11 | 12 | # This hook includes three examples. The first comments out the 13 | # "Conflicts:" part of a merge commit. 14 | # 15 | # The second includes the output of "git diff --name-status -r" 16 | # into the message, just before the "git status" output. It is 17 | # commented because it doesn't cope with --amend or with squashed 18 | # commits. 19 | # 20 | # The third example adds a Signed-off-by line to the message, that can 21 | # still be edited. This is rarely a good idea. 22 | 23 | case "$2,$3" in 24 | merge,) 25 | perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; 26 | 27 | # ,|template,) 28 | # perl -i.bak -pe ' 29 | # print "\n" . `git diff --cached --name-status -r` 30 | # if /^#/ && $first++ == 0' "$1" ;; 31 | 32 | *) ;; 33 | esac 34 | 35 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 36 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 37 | -------------------------------------------------------------------------------- /test/fixtures/submodule/hooks/prepare-commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare the commit log message. 4 | # Called by git-commit with the name of the file that has the 5 | # commit message, followed by the description of the commit 6 | # message's source. The hook's purpose is to edit the commit 7 | # message file. If the hook fails with a non-zero status, 8 | # the commit is aborted. 9 | # 10 | # To enable this hook, rename this file to "prepare-commit-msg". 11 | 12 | # This hook includes three examples. The first comments out the 13 | # "Conflicts:" part of a merge commit. 14 | # 15 | # The second includes the output of "git diff --name-status -r" 16 | # into the message, just before the "git status" output. It is 17 | # commented because it doesn't cope with --amend or with squashed 18 | # commits. 19 | # 20 | # The third example adds a Signed-off-by line to the message, that can 21 | # still be edited. This is rarely a good idea. 22 | 23 | case "$2,$3" in 24 | merge,) 25 | perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; 26 | 27 | # ,|template,) 28 | # perl -i.bak -pe ' 29 | # print "\n" . `git diff --cached --name-status -r` 30 | # if /^#/ && $first++ == 0' "$1" ;; 31 | 32 | *) ;; 33 | esac 34 | 35 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 36 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 37 | -------------------------------------------------------------------------------- /test/fixtures/no_branch/hooks/prepare-commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare the commit log message. 4 | # Called by "git commit" with the name of the file that has the 5 | # commit message, followed by the description of the commit 6 | # message's source. The hook's purpose is to edit the commit 7 | # message file. If the hook fails with a non-zero status, 8 | # the commit is aborted. 9 | # 10 | # To enable this hook, rename this file to "prepare-commit-msg". 11 | 12 | # This hook includes three examples. The first comments out the 13 | # "Conflicts:" part of a merge commit. 14 | # 15 | # The second includes the output of "git diff --name-status -r" 16 | # into the message, just before the "git status" output. It is 17 | # commented because it doesn't cope with --amend or with squashed 18 | # commits. 19 | # 20 | # The third example adds a Signed-off-by line to the message, that can 21 | # still be edited. This is rarely a good idea. 22 | 23 | case "$2,$3" in 24 | merge,) 25 | /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; 26 | 27 | # ,|template,) 28 | # /usr/bin/perl -i.bak -pe ' 29 | # print "\n" . `git diff --cached --name-status -r` 30 | # if /^#/ && $first++ == 0' "$1" ;; 31 | 32 | *) ;; 33 | esac 34 | 35 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 36 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 37 | -------------------------------------------------------------------------------- /test/fixtures/no_branch/hooks/pre-push.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # An example hook script to verify what is about to be pushed. Called by "git 4 | # push" after it has checked the remote status, but before anything has been 5 | # pushed. If this script exits with a non-zero status nothing will be pushed. 6 | # 7 | # This hook is called with the following parameters: 8 | # 9 | # $1 -- Name of the remote to which the push is being done 10 | # $2 -- URL to which the push is being done 11 | # 12 | # If pushing without using a named remote those arguments will be equal. 13 | # 14 | # Information about the commits which are being pushed is supplied as lines to 15 | # the standard input in the form: 16 | # 17 | # 18 | # 19 | # This sample shows how to prevent push of commits where the log message starts 20 | # with "WIP" (work in progress). 21 | 22 | remote="$1" 23 | url="$2" 24 | 25 | z40=0000000000000000000000000000000000000000 26 | 27 | IFS=' ' 28 | while read local_ref local_sha remote_ref remote_sha 29 | do 30 | if [ "$local_sha" = $z40 ] 31 | then 32 | # Handle delete 33 | : 34 | else 35 | if [ "$remote_sha" = $z40 ] 36 | then 37 | # New branch, examine all commits 38 | range="$local_sha" 39 | else 40 | # Update to existing branch, examine new commits 41 | range="$remote_sha..$local_sha" 42 | fi 43 | 44 | # Check for WIP commit 45 | commit=`git rev-list -n 1 --grep '^WIP' "$range"` 46 | if [ -n "$commit" ] 47 | then 48 | echo "Found WIP commit in $local_ref, not pushing" 49 | exit 1 50 | fi 51 | fi 52 | done 53 | 54 | exit 0 55 | -------------------------------------------------------------------------------- /test/commit.test.coffee: -------------------------------------------------------------------------------- 1 | should = require 'should' 2 | fixtures = require './fixtures' 3 | git = require '../src' 4 | Commit = require '../src/commit' 5 | Tree = require '../src/tree' 6 | 7 | describe "Commit", -> 8 | describe "#tree", -> 9 | repo = git "#{__dirname}/fixtures/branched" 10 | tree = null 11 | before (done) -> 12 | repo.commits "master", (err, commits) -> 13 | tree = commits[0].tree() 14 | done err 15 | 16 | it "passes a tree", -> 17 | tree.should.be.an.instanceof Tree 18 | 19 | 20 | describe "#parents", -> 21 | repo = fixtures.branched 22 | parents = null 23 | parent = null 24 | before (done) -> 25 | repo.commits "something", (err, commits) -> 26 | parents = commits[0].parents() 27 | parent = commits[1] 28 | done err 29 | 30 | it "is an Array of Commits", -> 31 | parents.should.be.an.instanceof Array 32 | parents[0].should.be.an.instanceof Commit 33 | 34 | it "has the parent commit", -> 35 | parents[0].id.should.eql parent.id 36 | 37 | describe "#describe", -> 38 | repo = fixtures.branched 39 | commit = null 40 | before (done) -> 41 | repo.commits "something", (err, commits) -> 42 | commit = commits[0] 43 | done err 44 | 45 | it "should be a long description", (done) -> 46 | repo.commits "something", (err, commits) -> 47 | commit.describe 'all', (err, description) -> 48 | # long descriptions have a '-g' in them to separate the sha-1 49 | (/-g/.test description).should.eql true 50 | done err 51 | -------------------------------------------------------------------------------- /src/ref.coffee: -------------------------------------------------------------------------------- 1 | fs = require 'fs' 2 | Commit = require './commit' 3 | 4 | exports.Ref = class Ref 5 | constructor: (@name, @commit) -> 6 | {@repo} = @commit 7 | 8 | # Public: Get a String representation of the Ref. 9 | toString: -> 10 | "#" 11 | 12 | # Internal: Find all refs. 13 | # 14 | # options - (optional). 15 | # 16 | # Returns Array of Ref. 17 | @find_all: (repo, type, RefClass, callback) -> 18 | repo.git.refs type, {}, (err, text) -> 19 | return callback err if err 20 | names = [] 21 | ids = [] 22 | for ref in text.split("\n") 23 | continue if !ref 24 | [name, id] = ref.split(' ') 25 | names.push name 26 | ids.push id 27 | 28 | Commit.find_commits repo, ids, (err, commits) -> 29 | return callback err if err 30 | refs = [] 31 | for name, i in names 32 | refs.push new RefClass name, commits[i] 33 | return callback null, refs 34 | 35 | 36 | exports.Head = class Head extends Ref 37 | @find_all: (repo, callback) -> 38 | Ref.find_all repo, "head", Head, callback 39 | 40 | @current: (repo, callback) -> 41 | fs.readFile "#{repo.dot_git}/HEAD", "utf8", (err, data) -> 42 | return callback err if err 43 | 44 | ref = /ref: refs\/heads\/([^\s]+)/.exec data 45 | # When the current branch check out to a commit, instaed of a branch name. 46 | return callback new Error "Current branch is not a valid branch." if !ref 47 | 48 | [m, branch] = ref 49 | fs.readFile "#{repo.dot_git}/refs/heads/#{branch}", "utf8", (err, id) -> 50 | Commit.find repo, id.trim(), (err, commit) -> 51 | return callback err if err 52 | return callback null, (new Head branch, commit) 53 | -------------------------------------------------------------------------------- /test/fixtures/branched/hooks/pre-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed. 4 | # Called by git-commit with no arguments. The hook should 5 | # exit with non-zero status after issuing an appropriate message if 6 | # it wants to stop the commit. 7 | # 8 | # To enable this hook, rename this file to "pre-commit". 9 | 10 | if git-rev-parse --verify HEAD >/dev/null 2>&1 11 | then 12 | against=HEAD 13 | else 14 | # Initial commit: diff against an empty tree object 15 | against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 16 | fi 17 | 18 | # If you want to allow non-ascii filenames set this variable to true. 19 | allownonascii=$(git config hooks.allownonascii) 20 | 21 | # Cross platform projects tend to avoid non-ascii filenames; prevent 22 | # them from being added to the repository. We exploit the fact that the 23 | # printable range starts at the space character and ends with tilde. 24 | if [ "$allownonascii" != "true" ] && 25 | # Note that the use of brackets around a tr range is ok here, (it's 26 | # even required, for portability to Solaris 10's /usr/bin/tr), since 27 | # the square bracket bytes happen to fall in the designated range. 28 | test "$(git diff --cached --name-only --diff-filter=A -z $against | 29 | LC_ALL=C tr -d '[ -~]\0')" 30 | then 31 | echo "Error: Attempt to add a non-ascii file name." 32 | echo 33 | echo "This can cause problems if you want to work" 34 | echo "with people on other platforms." 35 | echo 36 | echo "To be portable it is advisable to rename the file ..." 37 | echo 38 | echo "If you know what you are doing you can disable this" 39 | echo "check using:" 40 | echo 41 | echo " git config hooks.allownonascii true" 42 | echo 43 | exit 1 44 | fi 45 | 46 | exec git diff-index --check --cached $against -- 47 | -------------------------------------------------------------------------------- /test/fixtures/checkout/hooks/pre-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed. 4 | # Called by git-commit with no arguments. The hook should 5 | # exit with non-zero status after issuing an appropriate message if 6 | # it wants to stop the commit. 7 | # 8 | # To enable this hook, rename this file to "pre-commit". 9 | 10 | if git-rev-parse --verify HEAD >/dev/null 2>&1 11 | then 12 | against=HEAD 13 | else 14 | # Initial commit: diff against an empty tree object 15 | against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 16 | fi 17 | 18 | # If you want to allow non-ascii filenames set this variable to true. 19 | allownonascii=$(git config hooks.allownonascii) 20 | 21 | # Cross platform projects tend to avoid non-ascii filenames; prevent 22 | # them from being added to the repository. We exploit the fact that the 23 | # printable range starts at the space character and ends with tilde. 24 | if [ "$allownonascii" != "true" ] && 25 | # Note that the use of brackets around a tr range is ok here, (it's 26 | # even required, for portability to Solaris 10's /usr/bin/tr), since 27 | # the square bracket bytes happen to fall in the designated range. 28 | test "$(git diff --cached --name-only --diff-filter=A -z $against | 29 | LC_ALL=C tr -d '[ -~]\0')" 30 | then 31 | echo "Error: Attempt to add a non-ascii file name." 32 | echo 33 | echo "This can cause problems if you want to work" 34 | echo "with people on other platforms." 35 | echo 36 | echo "To be portable it is advisable to rename the file ..." 37 | echo 38 | echo "If you know what you are doing you can disable this" 39 | echo "check using:" 40 | echo 41 | echo " git config hooks.allownonascii true" 42 | echo 43 | exit 1 44 | fi 45 | 46 | exec git diff-index --check --cached $against -- 47 | -------------------------------------------------------------------------------- /test/fixtures/remotes/hooks/pre-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed. 4 | # Called by git-commit with no arguments. The hook should 5 | # exit with non-zero status after issuing an appropriate message if 6 | # it wants to stop the commit. 7 | # 8 | # To enable this hook, rename this file to "pre-commit". 9 | 10 | if git-rev-parse --verify HEAD >/dev/null 2>&1 11 | then 12 | against=HEAD 13 | else 14 | # Initial commit: diff against an empty tree object 15 | against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 16 | fi 17 | 18 | # If you want to allow non-ascii filenames set this variable to true. 19 | allownonascii=$(git config hooks.allownonascii) 20 | 21 | # Cross platform projects tend to avoid non-ascii filenames; prevent 22 | # them from being added to the repository. We exploit the fact that the 23 | # printable range starts at the space character and ends with tilde. 24 | if [ "$allownonascii" != "true" ] && 25 | # Note that the use of brackets around a tr range is ok here, (it's 26 | # even required, for portability to Solaris 10's /usr/bin/tr), since 27 | # the square bracket bytes happen to fall in the designated range. 28 | test "$(git diff --cached --name-only --diff-filter=A -z $against | 29 | LC_ALL=C tr -d '[ -~]\0')" 30 | then 31 | echo "Error: Attempt to add a non-ascii file name." 32 | echo 33 | echo "This can cause problems if you want to work" 34 | echo "with people on other platforms." 35 | echo 36 | echo "To be portable it is advisable to rename the file ..." 37 | echo 38 | echo "If you know what you are doing you can disable this" 39 | echo "check using:" 40 | echo 41 | echo " git config hooks.allownonascii true" 42 | echo 43 | exit 1 44 | fi 45 | 46 | exec git diff-index --check --cached $against -- 47 | -------------------------------------------------------------------------------- /test/fixtures/simple/hooks/pre-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed. 4 | # Called by git-commit with no arguments. The hook should 5 | # exit with non-zero status after issuing an appropriate message if 6 | # it wants to stop the commit. 7 | # 8 | # To enable this hook, rename this file to "pre-commit". 9 | 10 | if git-rev-parse --verify HEAD >/dev/null 2>&1 11 | then 12 | against=HEAD 13 | else 14 | # Initial commit: diff against an empty tree object 15 | against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 16 | fi 17 | 18 | # If you want to allow non-ascii filenames set this variable to true. 19 | allownonascii=$(git config hooks.allownonascii) 20 | 21 | # Cross platform projects tend to avoid non-ascii filenames; prevent 22 | # them from being added to the repository. We exploit the fact that the 23 | # printable range starts at the space character and ends with tilde. 24 | if [ "$allownonascii" != "true" ] && 25 | # Note that the use of brackets around a tr range is ok here, (it's 26 | # even required, for portability to Solaris 10's /usr/bin/tr), since 27 | # the square bracket bytes happen to fall in the designated range. 28 | test "$(git diff --cached --name-only --diff-filter=A -z $against | 29 | LC_ALL=C tr -d '[ -~]\0')" 30 | then 31 | echo "Error: Attempt to add a non-ascii file name." 32 | echo 33 | echo "This can cause problems if you want to work" 34 | echo "with people on other platforms." 35 | echo 36 | echo "To be portable it is advisable to rename the file ..." 37 | echo 38 | echo "If you know what you are doing you can disable this" 39 | echo "check using:" 40 | echo 41 | echo " git config hooks.allownonascii true" 42 | echo 43 | exit 1 44 | fi 45 | 46 | exec git diff-index --check --cached $against -- 47 | -------------------------------------------------------------------------------- /test/fixtures/status/hooks/pre-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed. 4 | # Called by git-commit with no arguments. The hook should 5 | # exit with non-zero status after issuing an appropriate message if 6 | # it wants to stop the commit. 7 | # 8 | # To enable this hook, rename this file to "pre-commit". 9 | 10 | if git-rev-parse --verify HEAD >/dev/null 2>&1 11 | then 12 | against=HEAD 13 | else 14 | # Initial commit: diff against an empty tree object 15 | against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 16 | fi 17 | 18 | # If you want to allow non-ascii filenames set this variable to true. 19 | allownonascii=$(git config hooks.allownonascii) 20 | 21 | # Cross platform projects tend to avoid non-ascii filenames; prevent 22 | # them from being added to the repository. We exploit the fact that the 23 | # printable range starts at the space character and ends with tilde. 24 | if [ "$allownonascii" != "true" ] && 25 | # Note that the use of brackets around a tr range is ok here, (it's 26 | # even required, for portability to Solaris 10's /usr/bin/tr), since 27 | # the square bracket bytes happen to fall in the designated range. 28 | test "$(git diff --cached --name-only --diff-filter=A -z $against | 29 | LC_ALL=C tr -d '[ -~]\0')" 30 | then 31 | echo "Error: Attempt to add a non-ascii file name." 32 | echo 33 | echo "This can cause problems if you want to work" 34 | echo "with people on other platforms." 35 | echo 36 | echo "To be portable it is advisable to rename the file ..." 37 | echo 38 | echo "If you know what you are doing you can disable this" 39 | echo "check using:" 40 | echo 41 | echo " git config hooks.allownonascii true" 42 | echo 43 | exit 1 44 | fi 45 | 46 | exec git diff-index --check --cached $against -- 47 | -------------------------------------------------------------------------------- /test/fixtures/tagged/hooks/pre-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed. 4 | # Called by git-commit with no arguments. The hook should 5 | # exit with non-zero status after issuing an appropriate message if 6 | # it wants to stop the commit. 7 | # 8 | # To enable this hook, rename this file to "pre-commit". 9 | 10 | if git-rev-parse --verify HEAD >/dev/null 2>&1 11 | then 12 | against=HEAD 13 | else 14 | # Initial commit: diff against an empty tree object 15 | against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 16 | fi 17 | 18 | # If you want to allow non-ascii filenames set this variable to true. 19 | allownonascii=$(git config hooks.allownonascii) 20 | 21 | # Cross platform projects tend to avoid non-ascii filenames; prevent 22 | # them from being added to the repository. We exploit the fact that the 23 | # printable range starts at the space character and ends with tilde. 24 | if [ "$allownonascii" != "true" ] && 25 | # Note that the use of brackets around a tr range is ok here, (it's 26 | # even required, for portability to Solaris 10's /usr/bin/tr), since 27 | # the square bracket bytes happen to fall in the designated range. 28 | test "$(git diff --cached --name-only --diff-filter=A -z $against | 29 | LC_ALL=C tr -d '[ -~]\0')" 30 | then 31 | echo "Error: Attempt to add a non-ascii file name." 32 | echo 33 | echo "This can cause problems if you want to work" 34 | echo "with people on other platforms." 35 | echo 36 | echo "To be portable it is advisable to rename the file ..." 37 | echo 38 | echo "If you know what you are doing you can disable this" 39 | echo "check using:" 40 | echo 41 | echo " git config hooks.allownonascii true" 42 | echo 43 | exit 1 44 | fi 45 | 46 | exec git diff-index --check --cached $against -- 47 | -------------------------------------------------------------------------------- /test/fixtures/status_opts/hooks/pre-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed. 4 | # Called by git-commit with no arguments. The hook should 5 | # exit with non-zero status after issuing an appropriate message if 6 | # it wants to stop the commit. 7 | # 8 | # To enable this hook, rename this file to "pre-commit". 9 | 10 | if git-rev-parse --verify HEAD >/dev/null 2>&1 11 | then 12 | against=HEAD 13 | else 14 | # Initial commit: diff against an empty tree object 15 | against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 16 | fi 17 | 18 | # If you want to allow non-ascii filenames set this variable to true. 19 | allownonascii=$(git config hooks.allownonascii) 20 | 21 | # Cross platform projects tend to avoid non-ascii filenames; prevent 22 | # them from being added to the repository. We exploit the fact that the 23 | # printable range starts at the space character and ends with tilde. 24 | if [ "$allownonascii" != "true" ] && 25 | # Note that the use of brackets around a tr range is ok here, (it's 26 | # even required, for portability to Solaris 10's /usr/bin/tr), since 27 | # the square bracket bytes happen to fall in the designated range. 28 | test "$(git diff --cached --name-only --diff-filter=A -z $against | 29 | LC_ALL=C tr -d '[ -~]\0')" 30 | then 31 | echo "Error: Attempt to add a non-ascii file name." 32 | echo 33 | echo "This can cause problems if you want to work" 34 | echo "with people on other platforms." 35 | echo 36 | echo "To be portable it is advisable to rename the file ..." 37 | echo 38 | echo "If you know what you are doing you can disable this" 39 | echo "check using:" 40 | echo 41 | echo " git config hooks.allownonascii true" 42 | echo 43 | exit 1 44 | fi 45 | 46 | exec git diff-index --check --cached $against -- 47 | -------------------------------------------------------------------------------- /test/fixtures/submodule/hooks/pre-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed. 4 | # Called by git-commit with no arguments. The hook should 5 | # exit with non-zero status after issuing an appropriate message if 6 | # it wants to stop the commit. 7 | # 8 | # To enable this hook, rename this file to "pre-commit". 9 | 10 | if git-rev-parse --verify HEAD >/dev/null 2>&1 11 | then 12 | against=HEAD 13 | else 14 | # Initial commit: diff against an empty tree object 15 | against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 16 | fi 17 | 18 | # If you want to allow non-ascii filenames set this variable to true. 19 | allownonascii=$(git config hooks.allownonascii) 20 | 21 | # Cross platform projects tend to avoid non-ascii filenames; prevent 22 | # them from being added to the repository. We exploit the fact that the 23 | # printable range starts at the space character and ends with tilde. 24 | if [ "$allownonascii" != "true" ] && 25 | # Note that the use of brackets around a tr range is ok here, (it's 26 | # even required, for portability to Solaris 10's /usr/bin/tr), since 27 | # the square bracket bytes happen to fall in the designated range. 28 | test "$(git diff --cached --name-only --diff-filter=A -z $against | 29 | LC_ALL=C tr -d '[ -~]\0')" 30 | then 31 | echo "Error: Attempt to add a non-ascii file name." 32 | echo 33 | echo "This can cause problems if you want to work" 34 | echo "with people on other platforms." 35 | echo 36 | echo "To be portable it is advisable to rename the file ..." 37 | echo 38 | echo "If you know what you are doing you can disable this" 39 | echo "check using:" 40 | echo 41 | echo " git config hooks.allownonascii true" 42 | echo 43 | exit 1 44 | fi 45 | 46 | exec git diff-index --check --cached $against -- 47 | -------------------------------------------------------------------------------- /src/tag.coffee: -------------------------------------------------------------------------------- 1 | _ = require 'underscore' 2 | Commit = require './commit' 3 | Actor = require './actor' 4 | {Ref} = require './ref' 5 | 6 | module.exports = class Tag extends Ref 7 | @find_all: (repo, callback) -> 8 | Ref.find_all repo, "tag", Tag, callback 9 | 10 | 11 | # Public: Get the tag message. 12 | # 13 | # Returns String. 14 | message: (callback) -> 15 | @lazy (err, data) -> 16 | return callback err if err 17 | return callback null, data.message 18 | 19 | # Public: Get the tag author. 20 | # 21 | # Returns Actor. 22 | tagger: (callback) -> 23 | @lazy (err, data) -> 24 | return callback err if err 25 | return callback null, data.tagger 26 | 27 | # Public: Get the date that the tag was created. 28 | # 29 | # Returns Date. 30 | tag_date: (callback) -> 31 | @lazy (err, data) -> 32 | return callback err if err 33 | return callback null, data.tag_date 34 | 35 | # Internal: Load the tag data. 36 | lazy: (callback) -> 37 | return callback null, @_lazy_data if @_lazy_data 38 | @repo.git "cat-file", {}, ["tag", @name] 39 | , (err, stdout, stderr) => 40 | return callback err if err 41 | lines = stdout.split "\n" 42 | data = {} 43 | 44 | lines.shift() # object 4ae1cc5e6c7bb85b14ecdf221030c71d0654a42e 45 | lines.shift() # type commit 46 | lines.shift() # tag v0.0.2 47 | 48 | # bob 49 | author_line = lines.shift() 50 | [m, author, epoch] = /^.+? (.*) (\d+) .*$/.exec author_line 51 | 52 | data.tagger = Actor.from_string author 53 | data.tag_date = new Date epoch 54 | 55 | lines.shift() 56 | message = [] 57 | while line = lines.shift() 58 | message.push line 59 | data.message = message.join("\n") 60 | 61 | return callback null, (@_lazy_data = data) 62 | 63 | -------------------------------------------------------------------------------- /test/fixtures/no_branch/hooks/pre-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed. 4 | # Called by "git commit" with no arguments. The hook should 5 | # exit with non-zero status after issuing an appropriate message if 6 | # it wants to stop the commit. 7 | # 8 | # To enable this hook, rename this file to "pre-commit". 9 | 10 | if git rev-parse --verify HEAD >/dev/null 2>&1 11 | then 12 | against=HEAD 13 | else 14 | # Initial commit: diff against an empty tree object 15 | against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 16 | fi 17 | 18 | # If you want to allow non-ASCII filenames set this variable to true. 19 | allownonascii=$(git config --bool hooks.allownonascii) 20 | 21 | # Redirect output to stderr. 22 | exec 1>&2 23 | 24 | # Cross platform projects tend to avoid non-ASCII filenames; prevent 25 | # them from being added to the repository. We exploit the fact that the 26 | # printable range starts at the space character and ends with tilde. 27 | if [ "$allownonascii" != "true" ] && 28 | # Note that the use of brackets around a tr range is ok here, (it's 29 | # even required, for portability to Solaris 10's /usr/bin/tr), since 30 | # the square bracket bytes happen to fall in the designated range. 31 | test $(git diff --cached --name-only --diff-filter=A -z $against | 32 | LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 33 | then 34 | cat <<\EOF 35 | Error: Attempt to add a non-ASCII file name. 36 | 37 | This can cause problems if you want to work with people on other platforms. 38 | 39 | To be portable it is advisable to rename the file. 40 | 41 | If you know what you are doing you can disable this check using: 42 | 43 | git config hooks.allownonascii true 44 | EOF 45 | exit 1 46 | fi 47 | 48 | # If there are whitespace errors, print the offending file names and fail. 49 | exec git diff-index --check --cached $against -- 50 | -------------------------------------------------------------------------------- /src/submodule.coffee: -------------------------------------------------------------------------------- 1 | module.exports = class Submodule 2 | constructor: (@repo, options) -> 3 | {@id, @name, @mode} = options 4 | 5 | # Public: Get the URL of the submodule. 6 | # 7 | # treeish - String treeish to look up the url within. 8 | # callback - Receives `(err, url)`. 9 | # 10 | url: (treeish, callback) -> 11 | [treeish, callback] = [callback, treeish] if !callback 12 | treeish ?= "master" 13 | 14 | Submodule.config @repo, treeish, (err, config) => 15 | return callback err, config?[@name].url 16 | 17 | 18 | # Internal: Parse the `.gitmodules` file. 19 | # 20 | # repo - A Repo. 21 | # treeish - String 22 | # callback - Receives `(err, config)`, where the config object has 23 | # the submodule names as its keys. 24 | # 25 | # Examples 26 | # 27 | # The following `.gitmodules` file: 28 | # 29 | # [submodule "spoon-knife"] 30 | # path = spoon-knife 31 | # url = git://github.com/octocat/Spoon-Knife.git 32 | # 33 | # would parse to: 34 | # 35 | # { "spoon-knife": 36 | # { "path": "spoon-knife" 37 | # , "url": "git://github.com/octocat/Spoon-Knife.git" 38 | # } 39 | # } 40 | # 41 | @config: (repo, treeish, callback) -> 42 | repo.tree(treeish).find ".gitmodules", (err, blob) -> 43 | return callback err if err 44 | blob.data (err, data) -> 45 | return callback err if err 46 | 47 | conf = {} 48 | lines = data.split "\n" 49 | current = null 50 | while lines.length 51 | line = lines.shift() 52 | 53 | if match = /^\[submodule "(.+)"\]$/.exec line 54 | current = match[1] 55 | conf[current] = {} 56 | else if match = /^\s+([^\s]+)\s+[=]\s+(.+)$/.exec line 57 | conf[current][match[1]] = match[2] 58 | 59 | return callback null, conf 60 | -------------------------------------------------------------------------------- /src/index.coffee: -------------------------------------------------------------------------------- 1 | exec = require 'flex-exec' 2 | Repo = require './repo' 3 | 4 | # Public: Create a Repo from the given path. 5 | # 6 | # Returns Repo. 7 | module.exports = Git = (path, bare=false, git_options={ 8 | maxBuffer: Git.maxBuffer 9 | }) -> return new Repo path, bare, git_options 10 | 11 | # Public: maxBuffer size for git commands 12 | Git.maxBuffer = 5000 * 1024 13 | 14 | # Public: Initialize a git repository. 15 | # 16 | # path - The directory to run `git init .` in. 17 | # bare - Create a bare repository when true. 18 | # callback - Receives `(err, repo)`. 19 | # 20 | Git.init = (path, bare, callback) -> 21 | [bare, callback] = [callback, bare] if !callback 22 | if bare 23 | bash = ["git", "init", "--bare", "."] 24 | else 25 | bash = ["git", "init", "."] 26 | exec bash, {cwd: path} 27 | , (err, stdout, stderr) -> 28 | return callback err if err instanceof Error 29 | return callback null, (new Repo path, bare, { maxBuffer: Git.maxBuffer }) 30 | 31 | # Public: Clone a git repository. 32 | # 33 | # repository - The repository to clone from. 34 | # path - The directory to clone into. 35 | # depth - The specified number of revisions of shallow clone 36 | # callback - Receives `(err, repo)`. 37 | # 38 | Git.clone = (repository, path, depth = 0, branch = null, callback) -> 39 | if typeof branch is 'function' 40 | callback = branch 41 | branch = null 42 | if typeof depth is 'function' 43 | callback = depth 44 | depth = 0 45 | bash = ["git", "clone", repository, path] 46 | 47 | if branch isnt null and typeof branch is 'string' 48 | bash.push("--branch", branch) 49 | if depth isnt 0 and typeof depth is 'number' 50 | bash.push("--depth", depth) 51 | 52 | exec bash, (err, stdout, stderr) -> 53 | return callback err if err instanceof Error 54 | return callback null, (new Repo path, false, { maxBuffer: Git.maxBuffer }) 55 | -------------------------------------------------------------------------------- /test/ref.test.coffee: -------------------------------------------------------------------------------- 1 | _ = require 'underscore' 2 | should = require 'should' 3 | fixtures = require './fixtures' 4 | git = require '../src' 5 | Commit = require '../src/commit' 6 | 7 | {Ref, Head} = require '../src/ref' 8 | 9 | describe "Ref", -> 10 | describe ".find_all", -> 11 | describe "find remotes", -> 12 | repo = fixtures.remotes 13 | remotes = null 14 | before (done) -> 15 | Ref.find_all repo, "remote", Ref, (err, _remotes) -> 16 | remotes = _remotes 17 | done err 18 | 19 | it "is an Array of Refs", -> 20 | remotes.should.be.an.instanceof Array 21 | remotes[0].should.be.an.instanceof Ref 22 | 23 | it "the first item is a remote", -> 24 | remotes[0].name.should.eql "origin/HEAD" 25 | remotes[0].commit.should.be.an.instanceof Commit 26 | 27 | it "the second item is a remote", -> 28 | remotes[1].name.should.eql "origin/master" 29 | remotes[1].commit.should.be.an.instanceof Commit 30 | 31 | 32 | describe "Head", -> 33 | describe ".find_all", -> 34 | repo = fixtures.branched 35 | heads = null 36 | before (done) -> 37 | Head.find_all repo, (err, h) -> 38 | heads = h 39 | done err 40 | 41 | it "is an Array of Heads", -> 42 | heads.should.be.an.instanceof Array 43 | heads[0].should.be.an.instanceof Head 44 | 45 | it "contains the branches", -> 46 | heads.should.have.lengthOf 2 47 | names = _.map heads, ((b) -> b.name) 48 | names.should.containEql "master" 49 | names.should.containEql "something" 50 | 51 | 52 | describe ".current", -> 53 | repo = fixtures.branched 54 | branch = null 55 | before (done) -> 56 | Head.current repo, (err, b) -> 57 | branch = b 58 | done err 59 | 60 | it "is a Head", -> 61 | branch.should.be.an.instanceof Head 62 | 63 | it "has the correct name", -> 64 | branch.name.should.eql "master" 65 | -------------------------------------------------------------------------------- /test/status.test.coffee: -------------------------------------------------------------------------------- 1 | should = require 'should' 2 | fixtures = require './fixtures' 3 | git = require '../src' 4 | Status = require '../src/status' 5 | 6 | GIT_STATUS = """ 7 | M cheese.txt 8 | D crackers.txt 9 | M file.txt 10 | ?? pickles.txt 11 | """ 12 | GIT_STATUS_CLEAN = "" 13 | GIT_STATUS_NOT_CLEAN = """ 14 | A lib/index.js 15 | M npm-shrinkwrap.json 16 | M package.json 17 | """ 18 | 19 | describe "Status", -> 20 | describe "()", -> 21 | describe "when there are no changes", -> 22 | repo = fixtures.status 23 | status = new Status.Status repo 24 | status.parse GIT_STATUS_CLEAN 25 | 26 | it "is clean", -> 27 | status.clean.should.be.true 28 | 29 | describe "when there are changes", -> 30 | repo = fixtures.status 31 | status = new Status.Status repo 32 | status.parse GIT_STATUS_NOT_CLEAN 33 | it "is not clean", -> 34 | status.clean.should.be.false 35 | 36 | describe "when there are changes", -> 37 | repo = fixtures.status 38 | status = new Status.Status repo 39 | status.parse GIT_STATUS 40 | 41 | it "has a modified staged file", -> 42 | status.files["file.txt"].staged.should.be.true 43 | status.files["file.txt"].type.should.eql "M" 44 | status.files["file.txt"].tracked.should.be.true 45 | 46 | it "has a modified unstaged file", -> 47 | status.files["cheese.txt"].staged.should.be.false 48 | status.files["cheese.txt"].type.should.eql "M" 49 | status.files["cheese.txt"].tracked.should.be.true 50 | 51 | it "has a deleted file", -> 52 | status.files["crackers.txt"].staged.should.be.true 53 | status.files["crackers.txt"].type.should.eql "D" 54 | status.files["crackers.txt"].tracked.should.be.true 55 | 56 | it "has an untracked file", -> 57 | status.files["pickles.txt"].tracked.should.be.false 58 | should.not.exist status.files["pickles.txt"].type 59 | 60 | it "is not clean", -> 61 | status.clean.should.be.false 62 | -------------------------------------------------------------------------------- /test/blob.test.coffee: -------------------------------------------------------------------------------- 1 | should = require 'should' 2 | fixtures = require './fixtures' 3 | git = require '../src' 4 | Blob = require '../src/blob' 5 | 6 | describe "Blob", -> 7 | describe "constructor", -> 8 | repo = fixtures.branched 9 | blob = new Blob repo, {name: "X", mode: "Y", id: "abc"} 10 | it "assigns @name", -> 11 | blob.name.should.eql "X" 12 | it "assigns @mode", -> 13 | blob.mode.should.eql "Y" 14 | it "assigns @id", -> 15 | blob.id.should.eql "abc" 16 | 17 | 18 | describe "#data", -> 19 | describe "of a file off the root", -> 20 | repo = git "#{__dirname}/fixtures/branched" 21 | data = null 22 | before (done) -> 23 | repo.tree().blobs (err, blobs) -> 24 | blobs[0].data (err, _data) -> 25 | data = _data 26 | done err 27 | 28 | it "is a string", -> 29 | data.should.be.type "string" 30 | data.should.containEql "Bla" 31 | 32 | describe "of a file in a subdir", -> 33 | repo = git "#{__dirname}/fixtures/branched" 34 | data = null 35 | before (done) -> 36 | repo.tree().trees (err, trees) -> 37 | trees[0].blobs (err, blobs) -> 38 | blobs[0].data (err, _data) -> 39 | data = _data 40 | done err 41 | 42 | it "is a string", -> 43 | data.should.be.type "string" 44 | data.should.containEql "!!!" 45 | 46 | describe "#dataStream", -> 47 | describe "of a file off the root", -> 48 | repo = git "#{__dirname}/fixtures/branched" 49 | data = "" 50 | before (done) -> 51 | repo.tree().blobs (err, blobs) -> 52 | [dataStream, _] = blobs[0].dataStream() 53 | dataStream.on 'data', (buf) -> 54 | data += buf.toString() 55 | .on 'end', -> 56 | done() 57 | 58 | it "is a string", -> 59 | data.should.be.type "string" 60 | data.should.containEql "Bla" 61 | 62 | describe "of a file in a subdir", -> 63 | repo = git "#{__dirname}/fixtures/branched" 64 | data = "" 65 | before (done) -> 66 | repo.tree().trees (err, trees) -> 67 | trees[0].blobs (err, blobs) -> 68 | [dataStream, _] = blobs[0].dataStream() 69 | dataStream.on 'data', (buf) -> 70 | data += buf.toString() 71 | .on 'end', -> 72 | done() 73 | 74 | it "is a string", -> 75 | data.should.be.type "string" 76 | data.should.containEql "!!!" 77 | 78 | 79 | -------------------------------------------------------------------------------- /test/status_opts.test.coffee: -------------------------------------------------------------------------------- 1 | should = require 'should' 2 | fixtures = require './fixtures' 3 | git = require '../src' 4 | Status = require '../src/status' 5 | 6 | GIT_STATUS = """ 7 | M cheese.txt 8 | D crackers.txt 9 | M file.txt 10 | ?? pickles.txt 11 | ?? burger/ 12 | """ 13 | GIT_STATUS_OPT = """ 14 | M cheese.txt 15 | D crackers.txt 16 | M file.txt 17 | ?? pickles.txt 18 | ?? burger/bun.txt 19 | ?? burger/patty.txt 20 | """ 21 | GIT_STATUS_CLEAN = "" 22 | GIT_STATUS_NOT_CLEAN = """ 23 | A lib/index.js 24 | M npm-shrinkwrap.json 25 | M package.json 26 | """ 27 | 28 | describe "Status With Options", -> 29 | describe "()", -> 30 | describe "when there are no changes", -> 31 | repo = fixtures.status_opts 32 | status = new Status.Status repo 33 | status.parse GIT_STATUS_CLEAN 34 | 35 | it "is clean", -> 36 | status.clean.should.be.true 37 | 38 | describe "when there are changes", -> 39 | repo = fixtures.status_opts 40 | status = new Status.Status repo 41 | status.parse GIT_STATUS_NOT_CLEAN 42 | it "is not clean", -> 43 | status.clean.should.be.false 44 | 45 | describe "when there are changes", -> 46 | repo = fixtures.status_opts 47 | status = new Status.Status repo 48 | status.parse GIT_STATUS 49 | 50 | it "has a modified staged file", -> 51 | status.files["file.txt"].staged.should.be.true 52 | status.files["file.txt"].type.should.eql "M" 53 | status.files["file.txt"].tracked.should.be.true 54 | 55 | it "has a modified unstaged file", -> 56 | status.files["cheese.txt"].staged.should.be.false 57 | status.files["crackers.txt"].type.should.eql "D" 58 | status.files["cheese.txt"].type.should.eql "M" 59 | status.files["cheese.txt"].tracked.should.be.true 60 | 61 | it "has a deleted file", -> 62 | status.files["crackers.txt"].staged.should.be.true 63 | status.files["crackers.txt"].type.should.eql "D" 64 | status.files["crackers.txt"].tracked.should.be.true 65 | 66 | it "has an untracked file", -> 67 | status.files["pickles.txt"].tracked.should.be.false 68 | should.not.exist status.files["pickles.txt"].type 69 | 70 | it "has an untracked directory", -> 71 | status.files["burger/"].tracked.should.be.false 72 | should.not.exist status.files["burger/"].type 73 | 74 | it "is not clean", -> 75 | status.clean.should.be.false 76 | 77 | describe "when the -u option is specified", -> 78 | repo = fixtures.status_opts 79 | status = new Status.Status repo, "-u" 80 | status.parse GIT_STATUS_OPT 81 | 82 | it "lists files in untracked directories", -> 83 | status.files["burger/bun.txt"].tracked.should.be.false 84 | should.not.exist status.files["burger/bun.txt"].type 85 | status.files["burger/patty.txt"].tracked.should.be.false 86 | should.not.exist status.files["burger/patty.txt"].type 87 | -------------------------------------------------------------------------------- /test/index.test.coffee: -------------------------------------------------------------------------------- 1 | should = require 'should' 2 | git = require '../src' 3 | Repo = require '../src/repo' 4 | fs = require "fs-extra" 5 | exec = require 'flex-exec' 6 | 7 | describe "git", -> 8 | describe "()", -> 9 | repo = git "#{__dirname}/fixtures/simple" 10 | it "returns a Repo", -> 11 | repo.should.be.an.instanceof Repo 12 | 13 | describe "init()", -> 14 | repo = null 15 | newRepositoryDir = "#{__dirname}/fixtures/new" 16 | before (done) -> 17 | fs.mkdirSync newRepositoryDir 18 | git.init newRepositoryDir, (err, _repo) -> 19 | repo = _repo 20 | done err 21 | it "inits a Repo", -> 22 | repo.should.be.an.instanceof Repo 23 | bare = repo.bare || false 24 | bare.should.be.false 25 | after (done) -> 26 | fs.remove newRepositoryDir, done 27 | 28 | describe "init() bare", -> 29 | repo = null 30 | newRepositoryDir = "#{__dirname}/fixtures/bare" 31 | before (done) -> 32 | fs.mkdirSync newRepositoryDir 33 | git.init newRepositoryDir, true, (err, _repo) -> 34 | repo = _repo 35 | done err 36 | it "inits a bare Repo", -> 37 | repo.should.be.an.instanceof Repo 38 | bare = repo.bare || false 39 | bare.should.be.true 40 | after (done) -> 41 | fs.remove newRepositoryDir, done 42 | 43 | describe "clone()", -> 44 | @timeout 30000 45 | repo = null 46 | newRepositoryDir = "#{__dirname}/fixtures/clone" 47 | before (done) -> 48 | git.clone "https://github.com/notatestuser/gift.git", newRepositoryDir, (err, _repo) -> 49 | repo = _repo 50 | done err 51 | it "clone a repository", (done) -> 52 | repo.should.be.an.instanceof Repo 53 | repo.remote_list (err, remotes) -> 54 | remotes.should.have.length 1 55 | done() 56 | after (done) -> 57 | fs.remove newRepositoryDir, done 58 | 59 | describe "clone() with depth", -> 60 | @timeout 30000 61 | repo = null 62 | newRepositoryDir = "#{__dirname}/fixtures/clone_depth" 63 | before (done) -> 64 | git.clone "https://github.com/notatestuser/gift.git", newRepositoryDir, 1, (err, _repo) -> 65 | repo = _repo 66 | done err 67 | it "clone a repository", (done) -> 68 | repo.should.be.an.instanceof Repo 69 | repo.remote_list (err, remotes) -> 70 | remotes.should.have.length 1 71 | done() 72 | after (done) -> 73 | fs.remove newRepositoryDir, done 74 | 75 | describe "clone() with depth and branch", -> 76 | @timeout 30000 77 | repo = null 78 | newRepositoryDir = "#{__dirname}/fixtures/clone_depth_branch" 79 | before (done) -> 80 | git.clone "https://github.com/notatestuser/gift.git", newRepositoryDir, 1, "develop", (err, _repo) -> 81 | repo = _repo 82 | done err 83 | it "clone a repository", (done) -> 84 | repo.should.be.an.instanceof Repo 85 | repo.branch "develop", (err, head) -> 86 | done err 87 | after (done) -> 88 | fs.remove newRepositoryDir, done 89 | -------------------------------------------------------------------------------- /src/tree.coffee: -------------------------------------------------------------------------------- 1 | _ = require 'underscore' 2 | Blob = require './blob' 3 | Submodule = require './submodule' 4 | 5 | module.exports = class Tree 6 | # repo - A Repo. 7 | # options - An Object with properties "id", "name", and "mode"; 8 | # or just a String id. 9 | constructor: (@repo, options) -> 10 | if _.isString options 11 | @id = options 12 | else 13 | {@id, @name, @mode} = options 14 | 15 | 16 | # Public: Get the children of the tree. 17 | # 18 | # callback - Receives `(err, children)`, where children is a list 19 | # of Trees, Blobs, and Submodules. 20 | # 21 | contents: (callback) -> 22 | return callback null, @_contents if @_contents 23 | @repo.git "ls-tree", {}, @id 24 | , (err, stdout, stderr) => 25 | return callback err if err 26 | @_contents = [] 27 | for line in stdout.split("\n") 28 | @_contents.push @content_from_string(line) if line 29 | return callback null, @_contents 30 | , 'binary' 31 | 32 | 33 | # Public: Get the child blobs. 34 | # 35 | # callback - Receives `(err, blobs)`. 36 | # 37 | blobs: (callback) -> 38 | @contents (err, children) -> 39 | return callback err if err 40 | return callback null, _.filter children, (child) -> 41 | child instanceof Blob 42 | 43 | 44 | # Public: Get the child blobs. 45 | # 46 | # callback - Receives `(err, trees)`. 47 | # 48 | trees: (callback) -> 49 | @contents (err, children) -> 50 | return callback err if err 51 | return callback null, _.filter children, (child) -> 52 | child instanceof Tree 53 | 54 | 55 | # Public: Find the named object in this tree's contents. 56 | # 57 | # callback - Receives `(err, obj)` where obj is Tree, Blob, or null 58 | # if not found. 59 | # 60 | find: (file, callback) -> 61 | if /\//.test file 62 | [dir, rest] = file.split "/", 2 63 | @trees (err, _trees) => 64 | for tree in _trees 65 | return tree.find rest, callback if tree.name == dir 66 | return callback null, null 67 | else 68 | @contents (err, children) -> 69 | return callback err if err 70 | for child in children 71 | if child.name == file 72 | return callback null, child 73 | return callback null, null 74 | 75 | 76 | # Internal: Parse a Blob or Tree from the line. 77 | # 78 | # line - String 79 | # 80 | # Examples 81 | # 82 | # tree.content_from_string "100644 blob e4ff69dd8f19d770e9731b4bc424ccb695f0b5ad README.md" 83 | # # => # 84 | # 85 | # Returns Blob, Tree or Submodule. 86 | content_from_string: (line) -> 87 | [mode, type, id, name] = line.split /[\t ]+/, 4 88 | switch type 89 | when "tree" 90 | new Tree @repo, {id, name, mode} 91 | when "blob" 92 | new Blob @repo, {id, name, mode} 93 | when "link" 94 | new Blob @repo, {id, name, mode} 95 | when "commit" 96 | new Submodule @repo, {id, name, mode} 97 | else 98 | throw new Error "Invalid object type: '#{type}'" 99 | 100 | # Public: Get a String representation of the Tree. 101 | # 102 | # Returns String. 103 | toString: -> 104 | "#" 105 | -------------------------------------------------------------------------------- /src/git.coffee: -------------------------------------------------------------------------------- 1 | fs = require 'fs' 2 | {exec, spawn} = require 'child_process' 3 | 4 | module.exports = Git = (git_dir, dot_git, git_options) -> 5 | git_options ||= {} 6 | dot_git ||= "#{git_dir}/.git" 7 | 8 | git = (command, options, args, callback, encoding) -> 9 | [callback, args] = [args, callback] if !callback 10 | [callback, options] = [options, callback] if !callback 11 | options ?= {} 12 | options = options_to_argv options 13 | options = options.join " " 14 | args ?= [] 15 | args = args.join " " if args instanceof Array 16 | encoding ?= 'utf8' 17 | bash = "#{git_options.bin || Git.bin} #{command} #{options} #{args}" 18 | exec bash, { 19 | cwd: git_dir, 20 | encoding: encoding, 21 | maxBuffer: git_options.maxBuffer || 5000 * 1024 22 | }, callback 23 | return bash 24 | 25 | # Public: Passthrough for raw git commands 26 | # 27 | git.cmd = (command, options, args, callback, encoding) -> 28 | git command, options, args, callback, encoding 29 | 30 | # Public: stream results of git command 31 | # 32 | # This is used for large files that you'd need to stream. 33 | # 34 | # returns [outstream, errstream] 35 | # 36 | git.streamCmd = (command, options, args, encoding) -> 37 | options ?= {} 38 | options = options_to_argv options 39 | args ?= [] 40 | allargs = [command].concat(options).concat(args) 41 | encoding ?= 'utf8' 42 | process = spawn Git.bin, allargs, {cwd: git_dir, encoding: encoding} 43 | return [process.stdout, process.stderr] 44 | 45 | # Public: Get a list of the remote names. 46 | # 47 | # callback - Receives `(err, names)`. 48 | # 49 | git.list_remotes = (callback) -> 50 | fs.readdir "#{dot_git}/refs/remotes", (err, files) -> 51 | callback err, (files || []) 52 | 53 | 54 | # Public: Get the ref data string. 55 | # 56 | # type - Such as `remote` or `tag`. 57 | # callback - Receives `(err, stdout)`. 58 | # 59 | git.refs = (type, options, callback) -> 60 | [callback, options] = [options, callback] if !callback 61 | prefix = "refs/#{type}s/" 62 | 63 | git "show-ref", (err, text) -> 64 | # ignore error code 1: means no match 65 | err = null if err?.code is 1 66 | matches = [] 67 | for line in (text || "").split("\n") 68 | continue if !line 69 | [id, name] = line.split(' ') 70 | if name.substr(0, prefix.length) == prefix 71 | matches.push "#{name.substr(prefix.length)} #{id}" 72 | return callback err, matches.join("\n") 73 | 74 | return git 75 | 76 | 77 | # Public: The `git` command. 78 | Git.bin = "git" 79 | 80 | 81 | 82 | # Internal: Transform an Object into command line options. 83 | # 84 | # Returns an Array of String option arguments. 85 | Git.options_to_argv = options_to_argv = (options) -> 86 | argv = [] 87 | for key, val of options 88 | if key.length == 1 89 | if val == true 90 | argv.push "-#{key}" 91 | else if val == false 92 | # ignore 93 | else 94 | argv.push "-#{key}" 95 | argv.push val 96 | else 97 | if val == true 98 | argv.push "--#{key}" 99 | else if val == false 100 | # ignore 101 | else 102 | argv.push "--#{key}=#{val}" 103 | return argv 104 | -------------------------------------------------------------------------------- /src/diff.coffee: -------------------------------------------------------------------------------- 1 | _ = require 'underscore' 2 | Blob = require './blob' 3 | 4 | module.exports = class Diff 5 | constructor: (@repo, @a_path, @b_path, a_blob, b_blob 6 | , @a_mode, @b_mode, @new_file, @deleted_file, @diff 7 | , @renamed_file=false, @similarity_index=0) -> 8 | if a_blob isnt null 9 | @a_blob = new Blob @repo, {id: a_blob} 10 | @a_sha = a_blob 11 | if b_blob isnt null 12 | @b_blob = new Blob @repo, {id: b_blob} 13 | @b_sha = b_blob 14 | 15 | toJSON: -> 16 | {@a_path, @b_path, @a_mode, @b_mode, @new_file 17 | , @deleted_file, @diff, @renamed_file, @similarity_index} 18 | 19 | # Public: Parse the Diffs from the command output. 20 | # 21 | # text - String stdout of a `git diff` command. 22 | # 23 | # Returns Array of Diff. 24 | @parse: (repo, text) -> 25 | lines = text.split "\n" 26 | diffs = [] 27 | 28 | while lines.length && lines[0] 29 | # FIXME shift is O(n), so iterating n over O(n) operation might be O(n^2) 30 | [m, a_path, b_path] = ///^diff\s--git\s"?a/(.+?)"?\s"?b/(.+)"?$///.exec lines.shift() 31 | 32 | if /^old mode/.test lines[0] 33 | [m, a_mode] = /^old mode (\d+)/.exec lines.shift() 34 | [m, b_mode] = /^new mode (\d+)/.exec lines.shift() 35 | 36 | if !lines.length || /^diff --git/.test(lines[0]) 37 | diffs.push new Diff(repo, a_path, b_path, null, null, a_mode, b_mode, false, false, null) 38 | continue 39 | 40 | sim_index = 0 41 | new_file = false 42 | deleted_file = false 43 | renamed_file = false 44 | 45 | if /^new file/.test lines[0] 46 | [m, b_mode] = /^new file mode (.+)$/.exec lines.shift() 47 | a_mode = null 48 | new_file = true 49 | else if /^deleted file/.test lines[0] 50 | [m, a_mode] = /^deleted file mode (.+)$/.exec lines.shift() 51 | b_mode = null 52 | deleted_file = true 53 | else if m = /^similarity index (\d+)\%/.exec(lines[0]) 54 | sim_index = m[1].to_i 55 | renamed_file = true 56 | # shift away the 2 `rename from/to ...` lines 57 | lines.shift() 58 | lines.shift() 59 | 60 | [m, a_blob, b_blob, b_mode] = ///^index\s([0-9A-Fa-f]+)\.\.([0-9A-Fa-f]+)\s?(.+)?$///.exec lines.shift() 61 | b_mode = b_mode.trim() if b_mode 62 | 63 | diff_lines = [] 64 | while lines[0] && !/^diff/.test(lines[0]) 65 | diff_lines.push lines.shift() 66 | diff = diff_lines.join "\n" 67 | 68 | diffs.push new Diff(repo, a_path, b_path, a_blob, b_blob, a_mode, b_mode, new_file, deleted_file, diff, renamed_file, sim_index) 69 | 70 | return diffs 71 | 72 | # Public: Parse the raw diff format from the command output. 73 | # 74 | # text - String stdout of a `git diff` command. 75 | # 76 | # Returns Array of Diff. 77 | @parse_raw: (repo, text) -> 78 | lines = _.compact(text.split "\n") 79 | diffs = [] 80 | 81 | for line in lines 82 | line = line[1..-1] # get rid of leading ':' 83 | line = line.replace(/\.\.\./g, '') 84 | [a_mode, b_mode, a_sha, b_sha, status, a_path, b_path] = line.split(/\s/) 85 | b_path = a_path unless b_path 86 | new_file = status is 'M' 87 | deleted_file = status is 'D' 88 | renamed_file = status is 'R' 89 | 90 | diffs.push new Diff( 91 | repo, a_path, b_path, a_sha, b_sha, a_mode, b_mode, 92 | new_file, deleted_file, null, renamed_file, null 93 | ) 94 | 95 | return diffs 96 | -------------------------------------------------------------------------------- /test/tree.test.coffee: -------------------------------------------------------------------------------- 1 | should = require 'should' 2 | fixtures = require './fixtures' 3 | git = require '../src' 4 | Tree = require '../src/tree' 5 | Blob = require '../src/blob' 6 | Submodule = require '../src/submodule' 7 | 8 | describe "Tree", -> 9 | describe "#contents", -> 10 | describe "simple", -> 11 | repo = fixtures.branched 12 | tree = repo.tree() 13 | contents = null 14 | 15 | before (done) -> 16 | tree.contents (err, _contents) -> 17 | contents = _contents 18 | done err 19 | 20 | it "is an Array", -> 21 | contents.should.be.an.instanceof Array 22 | 23 | it "contains a Blob", -> 24 | contents[0].should.be.an.instanceof Blob 25 | contents[0].name.should.eql "README.md" 26 | 27 | it "contains a Tree", -> 28 | contents[1].should.be.an.instanceof Tree 29 | contents[1].name.should.eql "some" 30 | 31 | describe "with submodules", -> 32 | repo = fixtures.submodule 33 | tree = repo.tree() 34 | contents = null 35 | 36 | before (done) -> 37 | tree.contents (err, _contents) -> 38 | contents = _contents 39 | done err 40 | 41 | it "contains a Submodule", (done) -> 42 | contents[2].should.be.an.instanceof Submodule 43 | contents[2].name.should.eql "spoon-knife" 44 | contents[2].url (err, url) -> 45 | url.should.eql "git://github.com/octocat/Spoon-Knife.git" 46 | done err 47 | 48 | 49 | describe "#blobs", -> 50 | repo = fixtures.branched 51 | tree = repo.tree() 52 | blobs = null 53 | 54 | before (done) -> 55 | tree.blobs (err, _blobs) -> 56 | blobs = _blobs 57 | done err 58 | 59 | it "has only 1 item", -> 60 | blobs.should.have.lengthOf 1 61 | 62 | it "contains a Blob", -> 63 | blobs[0].should.be.an.instanceof Blob 64 | blobs[0].name.should.eql "README.md" 65 | 66 | 67 | describe "#trees", -> 68 | repo = fixtures.branched 69 | tree = repo.tree() 70 | trees = null 71 | 72 | before (done) -> 73 | tree.trees (err, _trees) -> 74 | trees = _trees 75 | done err 76 | 77 | it "has only 1 item", -> 78 | trees.should.have.lengthOf 1 79 | 80 | it "contains a Tree", -> 81 | trees[0].should.be.an.instanceof Tree 82 | trees[0].name.should.eql "some" 83 | 84 | 85 | describe "#find", -> 86 | repo = fixtures.branched 87 | tree = repo.tree() 88 | describe "find a file", -> 89 | blob = null 90 | before (done) -> 91 | tree.find "README.md", (err, _blob) -> 92 | blob = _blob 93 | done err 94 | 95 | it "finds the Blob", -> 96 | blob.should.be.an.instanceof Blob 97 | blob.name.should.eql "README.md" 98 | 99 | describe "find a directory", -> 100 | subtree = null 101 | before (done) -> 102 | tree.find "some", (err, _tree) -> 103 | subtree = _tree 104 | done err 105 | 106 | it "finds the Tree", -> 107 | subtree.should.be.an.instanceof Tree 108 | subtree.name.should.eql "some" 109 | 110 | describe "find inside a directory", -> 111 | blob = null 112 | before (done) -> 113 | tree.find "some/hi.txt", (err, _blob) -> 114 | blob = _blob 115 | done err 116 | 117 | it "finds the Blob", -> 118 | blob.should.be.an.instanceof Blob 119 | blob.name.should.eql "hi.txt" 120 | 121 | describe "find a nonexistant file", -> 122 | subtree = null 123 | before (done) -> 124 | tree.find "nonexistant", (err, _tree) -> 125 | subtree = _tree 126 | done err 127 | 128 | it "is null", -> 129 | should.not.exist subtree 130 | 131 | -------------------------------------------------------------------------------- /test/fixtures/branched/hooks/update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to blocks unannotated tags from entering. 4 | # Called by git-receive-pack with arguments: refname sha1-old sha1-new 5 | # 6 | # To enable this hook, rename this file to "update". 7 | # 8 | # Config 9 | # ------ 10 | # hooks.allowunannotated 11 | # This boolean sets whether unannotated tags will be allowed into the 12 | # repository. By default they won't be. 13 | # hooks.allowdeletetag 14 | # This boolean sets whether deleting tags will be allowed in the 15 | # repository. By default they won't be. 16 | # hooks.allowmodifytag 17 | # This boolean sets whether a tag may be modified after creation. By default 18 | # it won't be. 19 | # hooks.allowdeletebranch 20 | # This boolean sets whether deleting branches will be allowed in the 21 | # repository. By default they won't be. 22 | # hooks.denycreatebranch 23 | # This boolean sets whether remotely creating branches will be denied 24 | # in the repository. By default this is allowed. 25 | # 26 | 27 | # --- Command line 28 | refname="$1" 29 | oldrev="$2" 30 | newrev="$3" 31 | 32 | # --- Safety check 33 | if [ -z "$GIT_DIR" ]; then 34 | echo "Don't run this script from the command line." >&2 35 | echo " (if you want, you could supply GIT_DIR then run" >&2 36 | echo " $0 )" >&2 37 | exit 1 38 | fi 39 | 40 | if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then 41 | echo "Usage: $0 " >&2 42 | exit 1 43 | fi 44 | 45 | # --- Config 46 | allowunannotated=$(git config --bool hooks.allowunannotated) 47 | allowdeletebranch=$(git config --bool hooks.allowdeletebranch) 48 | denycreatebranch=$(git config --bool hooks.denycreatebranch) 49 | allowdeletetag=$(git config --bool hooks.allowdeletetag) 50 | allowmodifytag=$(git config --bool hooks.allowmodifytag) 51 | 52 | # check for no description 53 | projectdesc=$(sed -e '1q' "$GIT_DIR/description") 54 | case "$projectdesc" in 55 | "Unnamed repository"* | "") 56 | echo "*** Project description file hasn't been set" >&2 57 | exit 1 58 | ;; 59 | esac 60 | 61 | # --- Check types 62 | # if $newrev is 0000...0000, it's a commit to delete a ref. 63 | zero="0000000000000000000000000000000000000000" 64 | if [ "$newrev" = "$zero" ]; then 65 | newrev_type=delete 66 | else 67 | newrev_type=$(git-cat-file -t $newrev) 68 | fi 69 | 70 | case "$refname","$newrev_type" in 71 | refs/tags/*,commit) 72 | # un-annotated tag 73 | short_refname=${refname##refs/tags/} 74 | if [ "$allowunannotated" != "true" ]; then 75 | echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 76 | echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 77 | exit 1 78 | fi 79 | ;; 80 | refs/tags/*,delete) 81 | # delete tag 82 | if [ "$allowdeletetag" != "true" ]; then 83 | echo "*** Deleting a tag is not allowed in this repository" >&2 84 | exit 1 85 | fi 86 | ;; 87 | refs/tags/*,tag) 88 | # annotated tag 89 | if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 90 | then 91 | echo "*** Tag '$refname' already exists." >&2 92 | echo "*** Modifying a tag is not allowed in this repository." >&2 93 | exit 1 94 | fi 95 | ;; 96 | refs/heads/*,commit) 97 | # branch 98 | if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then 99 | echo "*** Creating a branch is not allowed in this repository" >&2 100 | exit 1 101 | fi 102 | ;; 103 | refs/heads/*,delete) 104 | # delete branch 105 | if [ "$allowdeletebranch" != "true" ]; then 106 | echo "*** Deleting a branch is not allowed in this repository" >&2 107 | exit 1 108 | fi 109 | ;; 110 | refs/remotes/*,commit) 111 | # tracking branch 112 | ;; 113 | refs/remotes/*,delete) 114 | # delete tracking branch 115 | if [ "$allowdeletebranch" != "true" ]; then 116 | echo "*** Deleting a tracking branch is not allowed in this repository" >&2 117 | exit 1 118 | fi 119 | ;; 120 | *) 121 | # Anything else (is there anything else?) 122 | echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 123 | exit 1 124 | ;; 125 | esac 126 | 127 | # --- Finished 128 | exit 0 129 | -------------------------------------------------------------------------------- /test/fixtures/checkout/hooks/update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to blocks unannotated tags from entering. 4 | # Called by git-receive-pack with arguments: refname sha1-old sha1-new 5 | # 6 | # To enable this hook, rename this file to "update". 7 | # 8 | # Config 9 | # ------ 10 | # hooks.allowunannotated 11 | # This boolean sets whether unannotated tags will be allowed into the 12 | # repository. By default they won't be. 13 | # hooks.allowdeletetag 14 | # This boolean sets whether deleting tags will be allowed in the 15 | # repository. By default they won't be. 16 | # hooks.allowmodifytag 17 | # This boolean sets whether a tag may be modified after creation. By default 18 | # it won't be. 19 | # hooks.allowdeletebranch 20 | # This boolean sets whether deleting branches will be allowed in the 21 | # repository. By default they won't be. 22 | # hooks.denycreatebranch 23 | # This boolean sets whether remotely creating branches will be denied 24 | # in the repository. By default this is allowed. 25 | # 26 | 27 | # --- Command line 28 | refname="$1" 29 | oldrev="$2" 30 | newrev="$3" 31 | 32 | # --- Safety check 33 | if [ -z "$GIT_DIR" ]; then 34 | echo "Don't run this script from the command line." >&2 35 | echo " (if you want, you could supply GIT_DIR then run" >&2 36 | echo " $0 )" >&2 37 | exit 1 38 | fi 39 | 40 | if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then 41 | echo "Usage: $0 " >&2 42 | exit 1 43 | fi 44 | 45 | # --- Config 46 | allowunannotated=$(git config --bool hooks.allowunannotated) 47 | allowdeletebranch=$(git config --bool hooks.allowdeletebranch) 48 | denycreatebranch=$(git config --bool hooks.denycreatebranch) 49 | allowdeletetag=$(git config --bool hooks.allowdeletetag) 50 | allowmodifytag=$(git config --bool hooks.allowmodifytag) 51 | 52 | # check for no description 53 | projectdesc=$(sed -e '1q' "$GIT_DIR/description") 54 | case "$projectdesc" in 55 | "Unnamed repository"* | "") 56 | echo "*** Project description file hasn't been set" >&2 57 | exit 1 58 | ;; 59 | esac 60 | 61 | # --- Check types 62 | # if $newrev is 0000...0000, it's a commit to delete a ref. 63 | zero="0000000000000000000000000000000000000000" 64 | if [ "$newrev" = "$zero" ]; then 65 | newrev_type=delete 66 | else 67 | newrev_type=$(git-cat-file -t $newrev) 68 | fi 69 | 70 | case "$refname","$newrev_type" in 71 | refs/tags/*,commit) 72 | # un-annotated tag 73 | short_refname=${refname##refs/tags/} 74 | if [ "$allowunannotated" != "true" ]; then 75 | echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 76 | echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 77 | exit 1 78 | fi 79 | ;; 80 | refs/tags/*,delete) 81 | # delete tag 82 | if [ "$allowdeletetag" != "true" ]; then 83 | echo "*** Deleting a tag is not allowed in this repository" >&2 84 | exit 1 85 | fi 86 | ;; 87 | refs/tags/*,tag) 88 | # annotated tag 89 | if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 90 | then 91 | echo "*** Tag '$refname' already exists." >&2 92 | echo "*** Modifying a tag is not allowed in this repository." >&2 93 | exit 1 94 | fi 95 | ;; 96 | refs/heads/*,commit) 97 | # branch 98 | if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then 99 | echo "*** Creating a branch is not allowed in this repository" >&2 100 | exit 1 101 | fi 102 | ;; 103 | refs/heads/*,delete) 104 | # delete branch 105 | if [ "$allowdeletebranch" != "true" ]; then 106 | echo "*** Deleting a branch is not allowed in this repository" >&2 107 | exit 1 108 | fi 109 | ;; 110 | refs/remotes/*,commit) 111 | # tracking branch 112 | ;; 113 | refs/remotes/*,delete) 114 | # delete tracking branch 115 | if [ "$allowdeletebranch" != "true" ]; then 116 | echo "*** Deleting a tracking branch is not allowed in this repository" >&2 117 | exit 1 118 | fi 119 | ;; 120 | *) 121 | # Anything else (is there anything else?) 122 | echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 123 | exit 1 124 | ;; 125 | esac 126 | 127 | # --- Finished 128 | exit 0 129 | -------------------------------------------------------------------------------- /test/fixtures/remotes/hooks/update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to blocks unannotated tags from entering. 4 | # Called by git-receive-pack with arguments: refname sha1-old sha1-new 5 | # 6 | # To enable this hook, rename this file to "update". 7 | # 8 | # Config 9 | # ------ 10 | # hooks.allowunannotated 11 | # This boolean sets whether unannotated tags will be allowed into the 12 | # repository. By default they won't be. 13 | # hooks.allowdeletetag 14 | # This boolean sets whether deleting tags will be allowed in the 15 | # repository. By default they won't be. 16 | # hooks.allowmodifytag 17 | # This boolean sets whether a tag may be modified after creation. By default 18 | # it won't be. 19 | # hooks.allowdeletebranch 20 | # This boolean sets whether deleting branches will be allowed in the 21 | # repository. By default they won't be. 22 | # hooks.denycreatebranch 23 | # This boolean sets whether remotely creating branches will be denied 24 | # in the repository. By default this is allowed. 25 | # 26 | 27 | # --- Command line 28 | refname="$1" 29 | oldrev="$2" 30 | newrev="$3" 31 | 32 | # --- Safety check 33 | if [ -z "$GIT_DIR" ]; then 34 | echo "Don't run this script from the command line." >&2 35 | echo " (if you want, you could supply GIT_DIR then run" >&2 36 | echo " $0 )" >&2 37 | exit 1 38 | fi 39 | 40 | if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then 41 | echo "Usage: $0 " >&2 42 | exit 1 43 | fi 44 | 45 | # --- Config 46 | allowunannotated=$(git config --bool hooks.allowunannotated) 47 | allowdeletebranch=$(git config --bool hooks.allowdeletebranch) 48 | denycreatebranch=$(git config --bool hooks.denycreatebranch) 49 | allowdeletetag=$(git config --bool hooks.allowdeletetag) 50 | allowmodifytag=$(git config --bool hooks.allowmodifytag) 51 | 52 | # check for no description 53 | projectdesc=$(sed -e '1q' "$GIT_DIR/description") 54 | case "$projectdesc" in 55 | "Unnamed repository"* | "") 56 | echo "*** Project description file hasn't been set" >&2 57 | exit 1 58 | ;; 59 | esac 60 | 61 | # --- Check types 62 | # if $newrev is 0000...0000, it's a commit to delete a ref. 63 | zero="0000000000000000000000000000000000000000" 64 | if [ "$newrev" = "$zero" ]; then 65 | newrev_type=delete 66 | else 67 | newrev_type=$(git-cat-file -t $newrev) 68 | fi 69 | 70 | case "$refname","$newrev_type" in 71 | refs/tags/*,commit) 72 | # un-annotated tag 73 | short_refname=${refname##refs/tags/} 74 | if [ "$allowunannotated" != "true" ]; then 75 | echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 76 | echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 77 | exit 1 78 | fi 79 | ;; 80 | refs/tags/*,delete) 81 | # delete tag 82 | if [ "$allowdeletetag" != "true" ]; then 83 | echo "*** Deleting a tag is not allowed in this repository" >&2 84 | exit 1 85 | fi 86 | ;; 87 | refs/tags/*,tag) 88 | # annotated tag 89 | if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 90 | then 91 | echo "*** Tag '$refname' already exists." >&2 92 | echo "*** Modifying a tag is not allowed in this repository." >&2 93 | exit 1 94 | fi 95 | ;; 96 | refs/heads/*,commit) 97 | # branch 98 | if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then 99 | echo "*** Creating a branch is not allowed in this repository" >&2 100 | exit 1 101 | fi 102 | ;; 103 | refs/heads/*,delete) 104 | # delete branch 105 | if [ "$allowdeletebranch" != "true" ]; then 106 | echo "*** Deleting a branch is not allowed in this repository" >&2 107 | exit 1 108 | fi 109 | ;; 110 | refs/remotes/*,commit) 111 | # tracking branch 112 | ;; 113 | refs/remotes/*,delete) 114 | # delete tracking branch 115 | if [ "$allowdeletebranch" != "true" ]; then 116 | echo "*** Deleting a tracking branch is not allowed in this repository" >&2 117 | exit 1 118 | fi 119 | ;; 120 | *) 121 | # Anything else (is there anything else?) 122 | echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 123 | exit 1 124 | ;; 125 | esac 126 | 127 | # --- Finished 128 | exit 0 129 | -------------------------------------------------------------------------------- /test/fixtures/simple/hooks/update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to blocks unannotated tags from entering. 4 | # Called by git-receive-pack with arguments: refname sha1-old sha1-new 5 | # 6 | # To enable this hook, rename this file to "update". 7 | # 8 | # Config 9 | # ------ 10 | # hooks.allowunannotated 11 | # This boolean sets whether unannotated tags will be allowed into the 12 | # repository. By default they won't be. 13 | # hooks.allowdeletetag 14 | # This boolean sets whether deleting tags will be allowed in the 15 | # repository. By default they won't be. 16 | # hooks.allowmodifytag 17 | # This boolean sets whether a tag may be modified after creation. By default 18 | # it won't be. 19 | # hooks.allowdeletebranch 20 | # This boolean sets whether deleting branches will be allowed in the 21 | # repository. By default they won't be. 22 | # hooks.denycreatebranch 23 | # This boolean sets whether remotely creating branches will be denied 24 | # in the repository. By default this is allowed. 25 | # 26 | 27 | # --- Command line 28 | refname="$1" 29 | oldrev="$2" 30 | newrev="$3" 31 | 32 | # --- Safety check 33 | if [ -z "$GIT_DIR" ]; then 34 | echo "Don't run this script from the command line." >&2 35 | echo " (if you want, you could supply GIT_DIR then run" >&2 36 | echo " $0 )" >&2 37 | exit 1 38 | fi 39 | 40 | if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then 41 | echo "Usage: $0 " >&2 42 | exit 1 43 | fi 44 | 45 | # --- Config 46 | allowunannotated=$(git config --bool hooks.allowunannotated) 47 | allowdeletebranch=$(git config --bool hooks.allowdeletebranch) 48 | denycreatebranch=$(git config --bool hooks.denycreatebranch) 49 | allowdeletetag=$(git config --bool hooks.allowdeletetag) 50 | allowmodifytag=$(git config --bool hooks.allowmodifytag) 51 | 52 | # check for no description 53 | projectdesc=$(sed -e '1q' "$GIT_DIR/description") 54 | case "$projectdesc" in 55 | "Unnamed repository"* | "") 56 | echo "*** Project description file hasn't been set" >&2 57 | exit 1 58 | ;; 59 | esac 60 | 61 | # --- Check types 62 | # if $newrev is 0000...0000, it's a commit to delete a ref. 63 | zero="0000000000000000000000000000000000000000" 64 | if [ "$newrev" = "$zero" ]; then 65 | newrev_type=delete 66 | else 67 | newrev_type=$(git-cat-file -t $newrev) 68 | fi 69 | 70 | case "$refname","$newrev_type" in 71 | refs/tags/*,commit) 72 | # un-annotated tag 73 | short_refname=${refname##refs/tags/} 74 | if [ "$allowunannotated" != "true" ]; then 75 | echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 76 | echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 77 | exit 1 78 | fi 79 | ;; 80 | refs/tags/*,delete) 81 | # delete tag 82 | if [ "$allowdeletetag" != "true" ]; then 83 | echo "*** Deleting a tag is not allowed in this repository" >&2 84 | exit 1 85 | fi 86 | ;; 87 | refs/tags/*,tag) 88 | # annotated tag 89 | if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 90 | then 91 | echo "*** Tag '$refname' already exists." >&2 92 | echo "*** Modifying a tag is not allowed in this repository." >&2 93 | exit 1 94 | fi 95 | ;; 96 | refs/heads/*,commit) 97 | # branch 98 | if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then 99 | echo "*** Creating a branch is not allowed in this repository" >&2 100 | exit 1 101 | fi 102 | ;; 103 | refs/heads/*,delete) 104 | # delete branch 105 | if [ "$allowdeletebranch" != "true" ]; then 106 | echo "*** Deleting a branch is not allowed in this repository" >&2 107 | exit 1 108 | fi 109 | ;; 110 | refs/remotes/*,commit) 111 | # tracking branch 112 | ;; 113 | refs/remotes/*,delete) 114 | # delete tracking branch 115 | if [ "$allowdeletebranch" != "true" ]; then 116 | echo "*** Deleting a tracking branch is not allowed in this repository" >&2 117 | exit 1 118 | fi 119 | ;; 120 | *) 121 | # Anything else (is there anything else?) 122 | echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 123 | exit 1 124 | ;; 125 | esac 126 | 127 | # --- Finished 128 | exit 0 129 | -------------------------------------------------------------------------------- /test/fixtures/status/hooks/update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to blocks unannotated tags from entering. 4 | # Called by git-receive-pack with arguments: refname sha1-old sha1-new 5 | # 6 | # To enable this hook, rename this file to "update". 7 | # 8 | # Config 9 | # ------ 10 | # hooks.allowunannotated 11 | # This boolean sets whether unannotated tags will be allowed into the 12 | # repository. By default they won't be. 13 | # hooks.allowdeletetag 14 | # This boolean sets whether deleting tags will be allowed in the 15 | # repository. By default they won't be. 16 | # hooks.allowmodifytag 17 | # This boolean sets whether a tag may be modified after creation. By default 18 | # it won't be. 19 | # hooks.allowdeletebranch 20 | # This boolean sets whether deleting branches will be allowed in the 21 | # repository. By default they won't be. 22 | # hooks.denycreatebranch 23 | # This boolean sets whether remotely creating branches will be denied 24 | # in the repository. By default this is allowed. 25 | # 26 | 27 | # --- Command line 28 | refname="$1" 29 | oldrev="$2" 30 | newrev="$3" 31 | 32 | # --- Safety check 33 | if [ -z "$GIT_DIR" ]; then 34 | echo "Don't run this script from the command line." >&2 35 | echo " (if you want, you could supply GIT_DIR then run" >&2 36 | echo " $0 )" >&2 37 | exit 1 38 | fi 39 | 40 | if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then 41 | echo "Usage: $0 " >&2 42 | exit 1 43 | fi 44 | 45 | # --- Config 46 | allowunannotated=$(git config --bool hooks.allowunannotated) 47 | allowdeletebranch=$(git config --bool hooks.allowdeletebranch) 48 | denycreatebranch=$(git config --bool hooks.denycreatebranch) 49 | allowdeletetag=$(git config --bool hooks.allowdeletetag) 50 | allowmodifytag=$(git config --bool hooks.allowmodifytag) 51 | 52 | # check for no description 53 | projectdesc=$(sed -e '1q' "$GIT_DIR/description") 54 | case "$projectdesc" in 55 | "Unnamed repository"* | "") 56 | echo "*** Project description file hasn't been set" >&2 57 | exit 1 58 | ;; 59 | esac 60 | 61 | # --- Check types 62 | # if $newrev is 0000...0000, it's a commit to delete a ref. 63 | zero="0000000000000000000000000000000000000000" 64 | if [ "$newrev" = "$zero" ]; then 65 | newrev_type=delete 66 | else 67 | newrev_type=$(git-cat-file -t $newrev) 68 | fi 69 | 70 | case "$refname","$newrev_type" in 71 | refs/tags/*,commit) 72 | # un-annotated tag 73 | short_refname=${refname##refs/tags/} 74 | if [ "$allowunannotated" != "true" ]; then 75 | echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 76 | echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 77 | exit 1 78 | fi 79 | ;; 80 | refs/tags/*,delete) 81 | # delete tag 82 | if [ "$allowdeletetag" != "true" ]; then 83 | echo "*** Deleting a tag is not allowed in this repository" >&2 84 | exit 1 85 | fi 86 | ;; 87 | refs/tags/*,tag) 88 | # annotated tag 89 | if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 90 | then 91 | echo "*** Tag '$refname' already exists." >&2 92 | echo "*** Modifying a tag is not allowed in this repository." >&2 93 | exit 1 94 | fi 95 | ;; 96 | refs/heads/*,commit) 97 | # branch 98 | if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then 99 | echo "*** Creating a branch is not allowed in this repository" >&2 100 | exit 1 101 | fi 102 | ;; 103 | refs/heads/*,delete) 104 | # delete branch 105 | if [ "$allowdeletebranch" != "true" ]; then 106 | echo "*** Deleting a branch is not allowed in this repository" >&2 107 | exit 1 108 | fi 109 | ;; 110 | refs/remotes/*,commit) 111 | # tracking branch 112 | ;; 113 | refs/remotes/*,delete) 114 | # delete tracking branch 115 | if [ "$allowdeletebranch" != "true" ]; then 116 | echo "*** Deleting a tracking branch is not allowed in this repository" >&2 117 | exit 1 118 | fi 119 | ;; 120 | *) 121 | # Anything else (is there anything else?) 122 | echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 123 | exit 1 124 | ;; 125 | esac 126 | 127 | # --- Finished 128 | exit 0 129 | -------------------------------------------------------------------------------- /test/fixtures/submodule/hooks/update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to blocks unannotated tags from entering. 4 | # Called by git-receive-pack with arguments: refname sha1-old sha1-new 5 | # 6 | # To enable this hook, rename this file to "update". 7 | # 8 | # Config 9 | # ------ 10 | # hooks.allowunannotated 11 | # This boolean sets whether unannotated tags will be allowed into the 12 | # repository. By default they won't be. 13 | # hooks.allowdeletetag 14 | # This boolean sets whether deleting tags will be allowed in the 15 | # repository. By default they won't be. 16 | # hooks.allowmodifytag 17 | # This boolean sets whether a tag may be modified after creation. By default 18 | # it won't be. 19 | # hooks.allowdeletebranch 20 | # This boolean sets whether deleting branches will be allowed in the 21 | # repository. By default they won't be. 22 | # hooks.denycreatebranch 23 | # This boolean sets whether remotely creating branches will be denied 24 | # in the repository. By default this is allowed. 25 | # 26 | 27 | # --- Command line 28 | refname="$1" 29 | oldrev="$2" 30 | newrev="$3" 31 | 32 | # --- Safety check 33 | if [ -z "$GIT_DIR" ]; then 34 | echo "Don't run this script from the command line." >&2 35 | echo " (if you want, you could supply GIT_DIR then run" >&2 36 | echo " $0 )" >&2 37 | exit 1 38 | fi 39 | 40 | if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then 41 | echo "Usage: $0 " >&2 42 | exit 1 43 | fi 44 | 45 | # --- Config 46 | allowunannotated=$(git config --bool hooks.allowunannotated) 47 | allowdeletebranch=$(git config --bool hooks.allowdeletebranch) 48 | denycreatebranch=$(git config --bool hooks.denycreatebranch) 49 | allowdeletetag=$(git config --bool hooks.allowdeletetag) 50 | allowmodifytag=$(git config --bool hooks.allowmodifytag) 51 | 52 | # check for no description 53 | projectdesc=$(sed -e '1q' "$GIT_DIR/description") 54 | case "$projectdesc" in 55 | "Unnamed repository"* | "") 56 | echo "*** Project description file hasn't been set" >&2 57 | exit 1 58 | ;; 59 | esac 60 | 61 | # --- Check types 62 | # if $newrev is 0000...0000, it's a commit to delete a ref. 63 | zero="0000000000000000000000000000000000000000" 64 | if [ "$newrev" = "$zero" ]; then 65 | newrev_type=delete 66 | else 67 | newrev_type=$(git-cat-file -t $newrev) 68 | fi 69 | 70 | case "$refname","$newrev_type" in 71 | refs/tags/*,commit) 72 | # un-annotated tag 73 | short_refname=${refname##refs/tags/} 74 | if [ "$allowunannotated" != "true" ]; then 75 | echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 76 | echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 77 | exit 1 78 | fi 79 | ;; 80 | refs/tags/*,delete) 81 | # delete tag 82 | if [ "$allowdeletetag" != "true" ]; then 83 | echo "*** Deleting a tag is not allowed in this repository" >&2 84 | exit 1 85 | fi 86 | ;; 87 | refs/tags/*,tag) 88 | # annotated tag 89 | if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 90 | then 91 | echo "*** Tag '$refname' already exists." >&2 92 | echo "*** Modifying a tag is not allowed in this repository." >&2 93 | exit 1 94 | fi 95 | ;; 96 | refs/heads/*,commit) 97 | # branch 98 | if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then 99 | echo "*** Creating a branch is not allowed in this repository" >&2 100 | exit 1 101 | fi 102 | ;; 103 | refs/heads/*,delete) 104 | # delete branch 105 | if [ "$allowdeletebranch" != "true" ]; then 106 | echo "*** Deleting a branch is not allowed in this repository" >&2 107 | exit 1 108 | fi 109 | ;; 110 | refs/remotes/*,commit) 111 | # tracking branch 112 | ;; 113 | refs/remotes/*,delete) 114 | # delete tracking branch 115 | if [ "$allowdeletebranch" != "true" ]; then 116 | echo "*** Deleting a tracking branch is not allowed in this repository" >&2 117 | exit 1 118 | fi 119 | ;; 120 | *) 121 | # Anything else (is there anything else?) 122 | echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 123 | exit 1 124 | ;; 125 | esac 126 | 127 | # --- Finished 128 | exit 0 129 | -------------------------------------------------------------------------------- /test/fixtures/tagged/hooks/update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to blocks unannotated tags from entering. 4 | # Called by git-receive-pack with arguments: refname sha1-old sha1-new 5 | # 6 | # To enable this hook, rename this file to "update". 7 | # 8 | # Config 9 | # ------ 10 | # hooks.allowunannotated 11 | # This boolean sets whether unannotated tags will be allowed into the 12 | # repository. By default they won't be. 13 | # hooks.allowdeletetag 14 | # This boolean sets whether deleting tags will be allowed in the 15 | # repository. By default they won't be. 16 | # hooks.allowmodifytag 17 | # This boolean sets whether a tag may be modified after creation. By default 18 | # it won't be. 19 | # hooks.allowdeletebranch 20 | # This boolean sets whether deleting branches will be allowed in the 21 | # repository. By default they won't be. 22 | # hooks.denycreatebranch 23 | # This boolean sets whether remotely creating branches will be denied 24 | # in the repository. By default this is allowed. 25 | # 26 | 27 | # --- Command line 28 | refname="$1" 29 | oldrev="$2" 30 | newrev="$3" 31 | 32 | # --- Safety check 33 | if [ -z "$GIT_DIR" ]; then 34 | echo "Don't run this script from the command line." >&2 35 | echo " (if you want, you could supply GIT_DIR then run" >&2 36 | echo " $0 )" >&2 37 | exit 1 38 | fi 39 | 40 | if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then 41 | echo "Usage: $0 " >&2 42 | exit 1 43 | fi 44 | 45 | # --- Config 46 | allowunannotated=$(git config --bool hooks.allowunannotated) 47 | allowdeletebranch=$(git config --bool hooks.allowdeletebranch) 48 | denycreatebranch=$(git config --bool hooks.denycreatebranch) 49 | allowdeletetag=$(git config --bool hooks.allowdeletetag) 50 | allowmodifytag=$(git config --bool hooks.allowmodifytag) 51 | 52 | # check for no description 53 | projectdesc=$(sed -e '1q' "$GIT_DIR/description") 54 | case "$projectdesc" in 55 | "Unnamed repository"* | "") 56 | echo "*** Project description file hasn't been set" >&2 57 | exit 1 58 | ;; 59 | esac 60 | 61 | # --- Check types 62 | # if $newrev is 0000...0000, it's a commit to delete a ref. 63 | zero="0000000000000000000000000000000000000000" 64 | if [ "$newrev" = "$zero" ]; then 65 | newrev_type=delete 66 | else 67 | newrev_type=$(git-cat-file -t $newrev) 68 | fi 69 | 70 | case "$refname","$newrev_type" in 71 | refs/tags/*,commit) 72 | # un-annotated tag 73 | short_refname=${refname##refs/tags/} 74 | if [ "$allowunannotated" != "true" ]; then 75 | echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 76 | echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 77 | exit 1 78 | fi 79 | ;; 80 | refs/tags/*,delete) 81 | # delete tag 82 | if [ "$allowdeletetag" != "true" ]; then 83 | echo "*** Deleting a tag is not allowed in this repository" >&2 84 | exit 1 85 | fi 86 | ;; 87 | refs/tags/*,tag) 88 | # annotated tag 89 | if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 90 | then 91 | echo "*** Tag '$refname' already exists." >&2 92 | echo "*** Modifying a tag is not allowed in this repository." >&2 93 | exit 1 94 | fi 95 | ;; 96 | refs/heads/*,commit) 97 | # branch 98 | if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then 99 | echo "*** Creating a branch is not allowed in this repository" >&2 100 | exit 1 101 | fi 102 | ;; 103 | refs/heads/*,delete) 104 | # delete branch 105 | if [ "$allowdeletebranch" != "true" ]; then 106 | echo "*** Deleting a branch is not allowed in this repository" >&2 107 | exit 1 108 | fi 109 | ;; 110 | refs/remotes/*,commit) 111 | # tracking branch 112 | ;; 113 | refs/remotes/*,delete) 114 | # delete tracking branch 115 | if [ "$allowdeletebranch" != "true" ]; then 116 | echo "*** Deleting a tracking branch is not allowed in this repository" >&2 117 | exit 1 118 | fi 119 | ;; 120 | *) 121 | # Anything else (is there anything else?) 122 | echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 123 | exit 1 124 | ;; 125 | esac 126 | 127 | # --- Finished 128 | exit 0 129 | -------------------------------------------------------------------------------- /test/fixtures/no_branch/hooks/update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to blocks unannotated tags from entering. 4 | # Called by "git receive-pack" with arguments: refname sha1-old sha1-new 5 | # 6 | # To enable this hook, rename this file to "update". 7 | # 8 | # Config 9 | # ------ 10 | # hooks.allowunannotated 11 | # This boolean sets whether unannotated tags will be allowed into the 12 | # repository. By default they won't be. 13 | # hooks.allowdeletetag 14 | # This boolean sets whether deleting tags will be allowed in the 15 | # repository. By default they won't be. 16 | # hooks.allowmodifytag 17 | # This boolean sets whether a tag may be modified after creation. By default 18 | # it won't be. 19 | # hooks.allowdeletebranch 20 | # This boolean sets whether deleting branches will be allowed in the 21 | # repository. By default they won't be. 22 | # hooks.denycreatebranch 23 | # This boolean sets whether remotely creating branches will be denied 24 | # in the repository. By default this is allowed. 25 | # 26 | 27 | # --- Command line 28 | refname="$1" 29 | oldrev="$2" 30 | newrev="$3" 31 | 32 | # --- Safety check 33 | if [ -z "$GIT_DIR" ]; then 34 | echo "Don't run this script from the command line." >&2 35 | echo " (if you want, you could supply GIT_DIR then run" >&2 36 | echo " $0 )" >&2 37 | exit 1 38 | fi 39 | 40 | if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then 41 | echo "usage: $0 " >&2 42 | exit 1 43 | fi 44 | 45 | # --- Config 46 | allowunannotated=$(git config --bool hooks.allowunannotated) 47 | allowdeletebranch=$(git config --bool hooks.allowdeletebranch) 48 | denycreatebranch=$(git config --bool hooks.denycreatebranch) 49 | allowdeletetag=$(git config --bool hooks.allowdeletetag) 50 | allowmodifytag=$(git config --bool hooks.allowmodifytag) 51 | 52 | # check for no description 53 | projectdesc=$(sed -e '1q' "$GIT_DIR/description") 54 | case "$projectdesc" in 55 | "Unnamed repository"* | "") 56 | echo "*** Project description file hasn't been set" >&2 57 | exit 1 58 | ;; 59 | esac 60 | 61 | # --- Check types 62 | # if $newrev is 0000...0000, it's a commit to delete a ref. 63 | zero="0000000000000000000000000000000000000000" 64 | if [ "$newrev" = "$zero" ]; then 65 | newrev_type=delete 66 | else 67 | newrev_type=$(git cat-file -t $newrev) 68 | fi 69 | 70 | case "$refname","$newrev_type" in 71 | refs/tags/*,commit) 72 | # un-annotated tag 73 | short_refname=${refname##refs/tags/} 74 | if [ "$allowunannotated" != "true" ]; then 75 | echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 76 | echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 77 | exit 1 78 | fi 79 | ;; 80 | refs/tags/*,delete) 81 | # delete tag 82 | if [ "$allowdeletetag" != "true" ]; then 83 | echo "*** Deleting a tag is not allowed in this repository" >&2 84 | exit 1 85 | fi 86 | ;; 87 | refs/tags/*,tag) 88 | # annotated tag 89 | if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 90 | then 91 | echo "*** Tag '$refname' already exists." >&2 92 | echo "*** Modifying a tag is not allowed in this repository." >&2 93 | exit 1 94 | fi 95 | ;; 96 | refs/heads/*,commit) 97 | # branch 98 | if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then 99 | echo "*** Creating a branch is not allowed in this repository" >&2 100 | exit 1 101 | fi 102 | ;; 103 | refs/heads/*,delete) 104 | # delete branch 105 | if [ "$allowdeletebranch" != "true" ]; then 106 | echo "*** Deleting a branch is not allowed in this repository" >&2 107 | exit 1 108 | fi 109 | ;; 110 | refs/remotes/*,commit) 111 | # tracking branch 112 | ;; 113 | refs/remotes/*,delete) 114 | # delete tracking branch 115 | if [ "$allowdeletebranch" != "true" ]; then 116 | echo "*** Deleting a tracking branch is not allowed in this repository" >&2 117 | exit 1 118 | fi 119 | ;; 120 | *) 121 | # Anything else (is there anything else?) 122 | echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 123 | exit 1 124 | ;; 125 | esac 126 | 127 | # --- Finished 128 | exit 0 129 | -------------------------------------------------------------------------------- /test/fixtures/status_opts/hooks/update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to blocks unannotated tags from entering. 4 | # Called by git-receive-pack with arguments: refname sha1-old sha1-new 5 | # 6 | # To enable this hook, rename this file to "update". 7 | # 8 | # Config 9 | # ------ 10 | # hooks.allowunannotated 11 | # This boolean sets whether unannotated tags will be allowed into the 12 | # repository. By default they won't be. 13 | # hooks.allowdeletetag 14 | # This boolean sets whether deleting tags will be allowed in the 15 | # repository. By default they won't be. 16 | # hooks.allowmodifytag 17 | # This boolean sets whether a tag may be modified after creation. By default 18 | # it won't be. 19 | # hooks.allowdeletebranch 20 | # This boolean sets whether deleting branches will be allowed in the 21 | # repository. By default they won't be. 22 | # hooks.denycreatebranch 23 | # This boolean sets whether remotely creating branches will be denied 24 | # in the repository. By default this is allowed. 25 | # 26 | 27 | # --- Command line 28 | refname="$1" 29 | oldrev="$2" 30 | newrev="$3" 31 | 32 | # --- Safety check 33 | if [ -z "$GIT_DIR" ]; then 34 | echo "Don't run this script from the command line." >&2 35 | echo " (if you want, you could supply GIT_DIR then run" >&2 36 | echo " $0 )" >&2 37 | exit 1 38 | fi 39 | 40 | if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then 41 | echo "Usage: $0 " >&2 42 | exit 1 43 | fi 44 | 45 | # --- Config 46 | allowunannotated=$(git config --bool hooks.allowunannotated) 47 | allowdeletebranch=$(git config --bool hooks.allowdeletebranch) 48 | denycreatebranch=$(git config --bool hooks.denycreatebranch) 49 | allowdeletetag=$(git config --bool hooks.allowdeletetag) 50 | allowmodifytag=$(git config --bool hooks.allowmodifytag) 51 | 52 | # check for no description 53 | projectdesc=$(sed -e '1q' "$GIT_DIR/description") 54 | case "$projectdesc" in 55 | "Unnamed repository"* | "") 56 | echo "*** Project description file hasn't been set" >&2 57 | exit 1 58 | ;; 59 | esac 60 | 61 | # --- Check types 62 | # if $newrev is 0000...0000, it's a commit to delete a ref. 63 | zero="0000000000000000000000000000000000000000" 64 | if [ "$newrev" = "$zero" ]; then 65 | newrev_type=delete 66 | else 67 | newrev_type=$(git-cat-file -t $newrev) 68 | fi 69 | 70 | case "$refname","$newrev_type" in 71 | refs/tags/*,commit) 72 | # un-annotated tag 73 | short_refname=${refname##refs/tags/} 74 | if [ "$allowunannotated" != "true" ]; then 75 | echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 76 | echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 77 | exit 1 78 | fi 79 | ;; 80 | refs/tags/*,delete) 81 | # delete tag 82 | if [ "$allowdeletetag" != "true" ]; then 83 | echo "*** Deleting a tag is not allowed in this repository" >&2 84 | exit 1 85 | fi 86 | ;; 87 | refs/tags/*,tag) 88 | # annotated tag 89 | if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 90 | then 91 | echo "*** Tag '$refname' already exists." >&2 92 | echo "*** Modifying a tag is not allowed in this repository." >&2 93 | exit 1 94 | fi 95 | ;; 96 | refs/heads/*,commit) 97 | # branch 98 | if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then 99 | echo "*** Creating a branch is not allowed in this repository" >&2 100 | exit 1 101 | fi 102 | ;; 103 | refs/heads/*,delete) 104 | # delete branch 105 | if [ "$allowdeletebranch" != "true" ]; then 106 | echo "*** Deleting a branch is not allowed in this repository" >&2 107 | exit 1 108 | fi 109 | ;; 110 | refs/remotes/*,commit) 111 | # tracking branch 112 | ;; 113 | refs/remotes/*,delete) 114 | # delete tracking branch 115 | if [ "$allowdeletebranch" != "true" ]; then 116 | echo "*** Deleting a tracking branch is not allowed in this repository" >&2 117 | exit 1 118 | fi 119 | ;; 120 | *) 121 | # Anything else (is there anything else?) 122 | echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 123 | exit 1 124 | ;; 125 | esac 126 | 127 | # --- Finished 128 | exit 0 129 | -------------------------------------------------------------------------------- /test/diff.test.coffee: -------------------------------------------------------------------------------- 1 | should = require 'should' 2 | fixtures = require './fixtures' 3 | git = require '../src' 4 | Diff = require '../src/diff' 5 | Blob = require '../src/blob' 6 | 7 | 8 | describe "Diff", -> 9 | describe ".parse", -> 10 | describe "simple editing", -> 11 | repo = fixtures.tagged 12 | stdout = """ 13 | diff --git a/file.txt b/file.txt 14 | index d00491f..48082f7 100644 15 | --- a/file.txt 16 | +++ b/file.txt 17 | @@ -1 +1 @@ 18 | -1 19 | +12 20 | """ 21 | diffs = Diff.parse repo, stdout 22 | 23 | it "is an Array of Diffs", -> 24 | diffs.should.be.an.instanceof Array 25 | diffs[0].should.be.an.instanceof Diff 26 | 27 | it "has one diff", -> 28 | diffs.should.have.lengthOf 1 29 | 30 | describe "the first diff", -> 31 | diff = diffs[0] 32 | 33 | it "has the repo", -> 34 | diff.repo.should.eql repo 35 | 36 | for blob in ["a_blob", "b_blob"] 37 | it "has a #{blob}", -> 38 | diff[blob].should.be.an.instanceof Blob 39 | 40 | for path in ["a_path", "b_path"] 41 | it "has a #{path}", -> 42 | diff[path].should.eql "file.txt" 43 | 44 | it "has a b_mode", -> 45 | diff.b_mode.should.eql "100644" 46 | 47 | for change in ["new_file", "renamed_file", "deleted_file"] 48 | it "#{change} is false", -> 49 | diff[change].should.be.false 50 | 51 | it "has a similarity_index of 0", -> 52 | diff.similarity_index.should.eql 0 53 | 54 | describe ".parse_raw", -> 55 | describe "simple editing", -> 56 | repo = fixtures.tagged 57 | stdout = """ 58 | :100644 100644 95f6539... 0466f13... M file.txt 59 | """ 60 | diffs = Diff.parse_raw repo, stdout 61 | 62 | it "is an Array of Diffs", -> 63 | diffs.should.be.an.instanceof Array 64 | diffs[0].should.be.an.instanceof Diff 65 | 66 | it "has one diff", -> 67 | diffs.should.have.lengthOf 1 68 | 69 | describe "the first diff", -> 70 | diff = diffs[0] 71 | 72 | it "has the repo", -> 73 | diff.repo.should.eql repo 74 | 75 | for blob in ["a_blob", "b_blob"] 76 | it "has a #{blob}", -> 77 | diff[blob].should.be.an.instanceof Blob 78 | 79 | for path in ["a_path", "b_path"] 80 | it "has a #{path}", -> 81 | diff[path].should.eql "file.txt" 82 | 83 | it "has a b_mode", -> 84 | diff.b_mode.should.eql "100644" 85 | 86 | for change in ["new_file", "renamed_file", "deleted_file"] 87 | it "#{change} is false", -> 88 | diff[change].should.be.false 89 | 90 | it "has a similarity_index of 0", -> 91 | diff.similarity_index.should.eql 0 92 | 93 | describe "delete a file", -> 94 | repo = fixtures.branched 95 | stdout = """ 96 | diff --git a/README.md b/README.md 97 | index e4ff69d..c0efd1c 100644 98 | --- a/README.md 99 | +++ b/README.md 100 | @@ -1 +1 @@ 101 | -Bla 102 | +Bla2 103 | diff --git a/some/hi.txt b/some/hi.txt 104 | deleted file mode 100644 105 | index 6f1de24..0000000 106 | --- a/some/hi.txt 107 | +++ /dev/null 108 | @@ -1 +0,0 @@ 109 | -!!! 110 | """ 111 | diffs = Diff.parse repo, stdout 112 | 113 | it "has 2 diffs", -> 114 | diffs.should.have.lengthOf 2 115 | 116 | describe "the second diff", -> 117 | diff = diffs[1] 118 | it "deletes a file", -> 119 | diff.deleted_file.should.be.true 120 | 121 | describe "create a file", -> 122 | repo = fixtures.branched 123 | stdout = """ 124 | diff --git a/some/hi.txt b/some/hi.txt 125 | new file mode 100644 126 | index 0000000..6f1de24 127 | --- /dev/null 128 | +++ b/some/hi.txt 129 | @@ -0,0 +1 @@ 130 | +!!! 131 | """ 132 | diffs = Diff.parse repo, stdout 133 | 134 | it "creates a file", -> 135 | diffs[0].new_file.should.be.true 136 | 137 | 138 | -------------------------------------------------------------------------------- /src/commit.coffee: -------------------------------------------------------------------------------- 1 | _ = require 'underscore' 2 | Actor = require './actor' 3 | Tree = require './tree' 4 | 5 | module.exports = class Commit 6 | constructor: (@repo, @id, parents, tree, @author, @authored_date, @committer, @committed_date, @gpgsig, @message) -> 7 | # Public: Get the commit's Tree. 8 | # 9 | # Returns Tree. 10 | @tree = _.memoize => (new Tree @repo, tree) 11 | 12 | # Public: Get the Commit's parent Commits. 13 | # 14 | # Returns an Array of Commits. 15 | @parents = _.memoize => 16 | _.map parents, (parent) => 17 | new Commit @repo, parent 18 | 19 | # Public: `git describe `. 20 | # 21 | # id - Commit sha-1 22 | # refs - ["all" or "tags"]; default is annotated tags 23 | # first_parent - A boolean indicating only the first parent should be followed. 24 | # callback - Receives `(err, description)`. 25 | # 26 | @describe = (refs, first_parent, callback) => 27 | [first_parent, callback] = [callback, first_parent] if !callback 28 | [refs, callback] = [callback, refs] if !callback 29 | options = {}; 30 | options.all = true if refs == "all" 31 | options.tags = true if refs == "tags" 32 | options.first-parent = true if !!first_parent 33 | options.long = true 34 | 35 | @repo.git "describe", options, @id 36 | , (err, stdout, stderr) -> 37 | return callback err if err 38 | return callback null, stdout.trim() 39 | 40 | toJSON: -> 41 | {@id, @author, @authored_date, @committer, @committed_date, @message} 42 | 43 | 44 | # Public: Find the matching commits. 45 | # 46 | # callback - Receives `(err, commits)` 47 | # 48 | @find_all: (repo, ref, options, callback) -> 49 | options = _.extend {pretty: "raw"}, options 50 | repo.git "rev-list", options, ref 51 | , (err, stdout, stderr) => 52 | return callback err if err 53 | return callback null, @parse_commits(repo, stdout) 54 | 55 | 56 | @find: (repo, id, callback) -> 57 | options = {pretty: "raw", "max-count": 1} 58 | repo.git "rev-list", options, id 59 | , (err, stdout, stderr) => 60 | return callback err if err 61 | return callback null, @parse_commits(repo, stdout)[0] 62 | 63 | 64 | @find_commits: (repo, ids, callback) -> 65 | commits = [] 66 | next = (i) -> 67 | if id = ids[i] 68 | Commit.find repo, id, (err, commit) -> 69 | return callback err if err 70 | commits.push commit 71 | next i + 1 72 | # Done: all commits loaded. 73 | else 74 | callback null, commits 75 | next 0 76 | 77 | 78 | # Internal: Parse the commits from `git rev-list` 79 | # 80 | # Return Commit[] 81 | @parse_commits: (repo, text) -> 82 | commits = [] 83 | lines = text.split "\n" 84 | while lines.length 85 | id = _.last lines.shift().split(" ") 86 | break if !/^[a-f0-9]{40}$/.test(id) 87 | tree = _.last lines.shift().split(" ") 88 | 89 | parents = [] 90 | while /^parent/.test lines[0] 91 | parents.push _.last lines.shift().split(" ") 92 | 93 | author_line = lines.shift() 94 | [author, authored_date] = @actor author_line 95 | 96 | committer_line = lines.shift() 97 | [committer, committed_date] = @actor committer_line 98 | 99 | gpgsig = [] 100 | if /^gpgsig/.test lines[0] 101 | gpgsig.push lines.shift().replace /^gpgsig /, '' 102 | while !/^ -----END PGP SIGNATURE-----$/.test lines[0] 103 | gpgsig.push lines.shift() 104 | gpgsig.push lines.shift() 105 | 106 | # if converted from mercurial gpgsig may be present with non-valid gpg lines 107 | # e.g. "kilnhgcopies646973742F2E6874616363657373 6170702F2E6874616363657373" 108 | # see https://github.com/notatestuser/gift/pull/62 109 | while /^kilnhgcopies/.test lines[0] 110 | lines.shift() 111 | 112 | # if converted from mercurial gpgsig may be present with non-valid gpg lines 113 | # e.g. "HG:extra rebase_source:6c01d74dd05f50ede33608fe3f1b2049d93abbda" 114 | # and "HG:rename-source hg" 115 | while /^HG:/.test lines[0] 116 | lines.shift() 117 | 118 | # not doing anything with this yet, but it's sometimes there 119 | if /^encoding/.test lines[0] 120 | encoding = _.last lines.shift().split(" ") 121 | 122 | lines.shift() if lines.length 123 | 124 | message_lines = [] 125 | while /^ {4}/.test lines[0] 126 | message_lines.push lines.shift()[4..-1] 127 | 128 | while lines[0]? && !lines[0].length 129 | lines.shift() 130 | 131 | commits.push new Commit(repo, id, parents, tree, author, authored_date, committer, committed_date, gpgsig.join("\n"), message_lines.join("\n")) 132 | return commits 133 | 134 | 135 | # Internal: Parse the actor. 136 | # 137 | # Returns [String name and email, Date] 138 | @actor: (line) -> 139 | [m, actor, epoch] = /^.+? (.*) (\d+) .*$/.exec line 140 | return [Actor.from_string(actor), new Date(1000 * +epoch)] 141 | --------------------------------------------------------------------------------