Show More
@@ -0,0 +1,58 b'' | |||||
|
1 | $ "$TESTDIR/hghave" git || exit 80 | |||
|
2 | ||||
|
3 | make git commits repeatable | |||
|
4 | ||||
|
5 | $ GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME | |||
|
6 | $ GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL | |||
|
7 | $ GIT_AUTHOR_DATE='1234567891 +0000'; export GIT_AUTHOR_DATE | |||
|
8 | $ GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME | |||
|
9 | $ GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL | |||
|
10 | $ GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE | |||
|
11 | ||||
|
12 | root hg repo | |||
|
13 | ||||
|
14 | $ hg init t | |||
|
15 | $ cd t | |||
|
16 | $ echo a > a | |||
|
17 | $ hg add a | |||
|
18 | $ hg commit -m a | |||
|
19 | $ cd .. | |||
|
20 | ||||
|
21 | new external git repo | |||
|
22 | ||||
|
23 | $ mkdir gitroot | |||
|
24 | $ cd gitroot | |||
|
25 | $ git init -q | |||
|
26 | $ echo g > g | |||
|
27 | $ git add g | |||
|
28 | $ git commit -q -m g | |||
|
29 | ||||
|
30 | add subrepo clone | |||
|
31 | ||||
|
32 | $ cd ../t | |||
|
33 | $ echo 's = [git]../gitroot' > .hgsub | |||
|
34 | $ git clone -q ../gitroot s | |||
|
35 | $ hg add .hgsub | |||
|
36 | $ hg commit -m 'new git subrepo' | |||
|
37 | committing subrepository $TESTTMP/t/s | |||
|
38 | $ hg debugsub | |||
|
39 | path s | |||
|
40 | source ../gitroot | |||
|
41 | revision da5f5b1d8ffcf62fb8327bcd3c89a4367a6018e7 | |||
|
42 | ||||
|
43 | record a new commit from upstream | |||
|
44 | ||||
|
45 | $ cd ../gitroot | |||
|
46 | $ echo gg >> g | |||
|
47 | $ git commit -q -a -m gg | |||
|
48 | ||||
|
49 | $ cd ../t/s | |||
|
50 | $ git pull -q | |||
|
51 | ||||
|
52 | $ cd .. | |||
|
53 | $ hg commit -m 'update git subrepo' | |||
|
54 | committing subrepository $TESTTMP/t/s | |||
|
55 | $ hg debugsub | |||
|
56 | path s | |||
|
57 | source ../gitroot | |||
|
58 | revision 126f2a14290cd5ce061fdedc430170e8d39e1c5a |
@@ -5,7 +5,7 b'' | |||||
5 | # This software may be used and distributed according to the terms of the |
|
5 | # This software may be used and distributed according to the terms of the | |
6 | # GNU General Public License version 2 or any later version. |
|
6 | # GNU General Public License version 2 or any later version. | |
7 |
|
7 | |||
8 | import errno, os, re, xml.dom.minidom, shutil, urlparse, posixpath |
|
8 | import errno, os, re, xml.dom.minidom, shutil, subprocess, urlparse, posixpath | |
9 | from i18n import _ |
|
9 | from i18n import _ | |
10 | import config, util, node, error, cmdutil |
|
10 | import config, util, node, error, cmdutil | |
11 | hg = None |
|
11 | hg = None | |
@@ -576,7 +576,87 b' class svnsubrepo(abstractsubrepo):' | |||||
576 | return self._svncommand(['cat'], name) |
|
576 | return self._svncommand(['cat'], name) | |
577 |
|
577 | |||
578 |
|
578 | |||
|
579 | class gitsubrepo(object): | |||
|
580 | def __init__(self, ctx, path, state): | |||
|
581 | # TODO add git version check. | |||
|
582 | self._state = state | |||
|
583 | self._ctx = ctx | |||
|
584 | self._path = ctx._repo.wjoin(path) | |||
|
585 | self._ui = ctx._repo.ui | |||
|
586 | ||||
|
587 | def _gitcommand(self, commands): | |||
|
588 | return self._gitdir(commands)[0] | |||
|
589 | ||||
|
590 | def _gitdir(self, commands): | |||
|
591 | commands = ['--no-pager', '--git-dir=%s/.git' % self._path, | |||
|
592 | '--work-tree=%s' % self._path] + commands | |||
|
593 | return self._gitnodir(commands) | |||
|
594 | ||||
|
595 | def _gitnodir(self, commands): | |||
|
596 | """Calls the git command | |||
|
597 | ||||
|
598 | The methods tries to call the git command. versions previor to 1.6.0 | |||
|
599 | are not supported and very probably fail. | |||
|
600 | """ | |||
|
601 | cmd = ['git'] + commands | |||
|
602 | cmd = [util.shellquote(arg) for arg in cmd] | |||
|
603 | cmd = util.quotecommand(' '.join(cmd)) | |||
|
604 | ||||
|
605 | # print git's stderr, which is mostly progress and useful info | |||
|
606 | p = subprocess.Popen(cmd, shell=True, bufsize=-1, | |||
|
607 | close_fds=(os.name == 'posix'), | |||
|
608 | stdout=subprocess.PIPE) | |||
|
609 | retdata = p.stdout.read() | |||
|
610 | # wait for the child to exit to avoid race condition. | |||
|
611 | p.wait() | |||
|
612 | ||||
|
613 | if p.returncode != 0: | |||
|
614 | # there are certain error codes that are ok | |||
|
615 | command = None | |||
|
616 | for arg in commands: | |||
|
617 | if not arg.startswith('-'): | |||
|
618 | command = arg | |||
|
619 | break | |||
|
620 | if command == 'cat-file': | |||
|
621 | return retdata, p.returncode | |||
|
622 | if command in ('commit', 'status') and p.returncode == 1: | |||
|
623 | return retdata, p.returncode | |||
|
624 | # for all others, abort | |||
|
625 | raise util.Abort('git %s error %d' % (command, p.returncode)) | |||
|
626 | ||||
|
627 | return retdata, p.returncode | |||
|
628 | ||||
|
629 | def _gitstate(self): | |||
|
630 | return self._gitcommand(['rev-parse', 'HEAD']).strip() | |||
|
631 | ||||
|
632 | def _githavelocally(self, revision): | |||
|
633 | out, code = self._gitdir(['cat-file', '-e', revision]) | |||
|
634 | return code == 0 | |||
|
635 | ||||
|
636 | def dirty(self): | |||
|
637 | if self._state[1] != self._gitstate(): # version checked out changed? | |||
|
638 | return True | |||
|
639 | # check for staged changes or modified files; ignore untracked files | |||
|
640 | # docs say --porcelain flag is future-proof format | |||
|
641 | changed = self._gitcommand(['status', '--porcelain', | |||
|
642 | '--untracked-files=no']) | |||
|
643 | return bool(changed.strip()) | |||
|
644 | ||||
|
645 | def commit(self, text, user, date): | |||
|
646 | cmd = ['commit', '-a', '-m', text] | |||
|
647 | if user: | |||
|
648 | cmd += ['--author', user] | |||
|
649 | if date: | |||
|
650 | # git's date parser silently ignores when seconds < 1e9 | |||
|
651 | # convert to ISO8601 | |||
|
652 | cmd += ['--date', util.datestr(date, '%Y-%m-%dT%H:%M:%S %1%2')] | |||
|
653 | self._gitcommand(cmd) | |||
|
654 | # make sure commit works otherwise HEAD might not exist under certain | |||
|
655 | # circumstances | |||
|
656 | return self._gitstate() | |||
|
657 | ||||
579 | types = { |
|
658 | types = { | |
580 | 'hg': hgsubrepo, |
|
659 | 'hg': hgsubrepo, | |
581 | 'svn': svnsubrepo, |
|
660 | 'svn': svnsubrepo, | |
|
661 | 'git': gitsubrepo, | |||
582 | } |
|
662 | } |
General Comments 0
You need to be logged in to leave comments.
Login now