示例#1
0
 def url_from_directory(directory, include_commit = True):
     with cd(directory):
         origin = log_check_output(['git', 'remote', 'get-url', 'origin'], universal_newlines=True)[:-1]
         commit = log_check_output(['git', 'log', '-1', '--format=%H'], universal_newlines=True)[:-1]
     ret = 'git+%s' % (origin,)
     if include_commit:
         ret += '#commit=%s' % (commit,)
     return ret
示例#2
0
        def actualUpdate():
            with cd(self.directory):
                try:
                    current_origin = log_check_output(['git', 'config', '--get', 'remote.origin.url']).strip().decode('utf-8')
                except CalledProcessError:
                    current_origin = None
                if current_origin != self.url.geturl():
                    # For now we just throw a fit; it shouldn't happen often,
                    # and in this case there's no "right" answer - the repo may
                    # have just moved, or we may be dealing with a completely
                    # unrelated repo.
                    # In future, it would be nice to be a bit more interactive
                    raise QuarkError("""

Directory '%s' is a git repository,
but its remote 'origin' (%r)
does not match what we expect (%r).

Please either remove the local clone, or fix its remote.""" % (self.directory, current_origin, self.url.geturl()))
                if self.conf.get("shallow", False):
                    # Fetch just the commit we need
                    fork(['git', 'fetch', '--depth', '1', 'origin', self.noremote_ref()])
                    # Notice that we need FETCH_HEAD, as the shallow clone does not recognize
                    # origin/HEAD & co.
                    fork(['git', 'checkout', 'FETCH_HEAD', '--'])
                else:
                    fork(['git', 'fetch'])
                    # If we want to go on a branch, try to find a local branch that tracks it
                    # and use it (possibly with a fast-forward)
                    if self.ref_type == 'branch':
                        # Resolve the remote ref
                        remote_fullref = self.symbolic_full_name(self.ref)
                        # Get a sensible local branch name to try
                        local_ref = remote_fullref.split('/origin/', 1)[1]
                        # Check if it is actually tracking our target
                        try:
                            local_fulltrackref = self.symbolic_full_name(local_ref + "@{u}")
                        except CalledProcessError:
                            # It's fine if it fails - we may not have a local-tracking branch,
                            # so git checkout will do the right thing here
                            local_fulltrackref = remote_fullref

                        if remote_fullref == local_fulltrackref:
                            try:
                                # Checkout and fast-forward
                                fork(['git', 'checkout', local_ref, '--'])
                                fork(['git', 'merge', '--ff-only', self.ref, '--'])
                                # Final sanity check
                                if log_check_output(['git', 'rev-parse', self.ref, '--']) != log_check_output(['git', 'rev-parse', local_ref, '--']):
                                    logger.warning("Warning: your local branch is ahead of required remote branch!")
                                return
                            except CalledProcessError:
                                logger.warning("Couldn't fast-forward local branch, fallback to detached head mode...")
                    # General case: plain checkout of the origin ref (going in detached HEAD)
                    fork(['git', 'checkout', self.ref, '--'])
示例#3
0
 def url_from_directory(directory, include_commit = True):
     xml = log_check_output(['svn', 'info', '--xml', directory], universal_newlines=True)
     doc = ElementTree.fromstring(xml)
     ret = doc.findall('./entry/url')[0].text
     if include_commit:
         ret += "@" + doc.findall('./entry/commit')[0].get('revision')
     return ret
示例#4
0
 def has_local_edit(self):
     xml = log_check_output(['svn', 'st', '--xml', self.directory],
                            universal_newlines=True)
     doc = ElementTree.fromstring(xml)
     return len(
         doc.findall('./target/entry/wc-status[@item="modified"]')) != 0
示例#5
0
 def symbolic_full_name(self, ref):
     with cd(self.directory):
         return log_check_output(
             ['git', 'rev-parse', '--symbolic-full-name', ref,
              '--']).split(b'\n')[0].strip().decode('utf-8')
示例#6
0
 def has_local_edit(self):
     with cd(self.directory):
         return log_check_output(['git', 'status', '--porcelain']) != b""
示例#7
0
        def actualUpdate():
            with cd(self.directory):
                try:
                    current_origin = log_check_output(
                        ['git', 'config', '--get',
                         'remote.origin.url']).strip().decode('utf-8')
                except CalledProcessError:
                    current_origin = None
                if current_origin != self.url.geturl():
                    # For now we just throw a fit; it shouldn't happen often,
                    # and in this case there's no "right" answer - the repo may
                    # have just moved, or we may be dealing with a completely
                    # unrelated repo.
                    # In future, it would be nice to be a bit more interactive
                    raise QuarkError(
                        """

Directory '%s' is a git repository,
but its remote 'origin' (%r)
does not match what we expect (%r).

Please either remove the local clone, or fix its remote.""" %
                        (self.directory, current_origin, self.url.geturl()))
                if self.conf.get("shallow", False):
                    # git fetch with shallow clones isn't very smart, and
                    # re-fetches stuff that we already have; try to avoid this

                    # FIXME: the current approach means that shallow clones
                    # will be in detached HEAD state to a commit pretty much
                    # always.
                    # Probably this is not a big problem because shallow repos
                    # in Quark aren't meant to be used for actual repo work,
                    # and the previous implementation always had FETCH_HEAD
                    # checked out; however, in future it would be nice to have
                    # a cleaner solution.

                    if self.ref_type == 'commit':
                        # Easy case: we already know exactly the commit we need
                        remote_commit = self.ref
                    else:
                        # Ask the remote what we are expected to have here
                        remote_commit = log_check_output([
                            'git', 'ls-remote', 'origin',
                            self.noremote_ref()
                        ]).split(b'\t')[0].strip().decode('utf-8')

                    try:
                        # Try to check it out; in the common case (nothing
                        # changed) this should be a no-op
                        fork(['git', 'checkout', remote_commit, '--'])
                    except CalledProcessError:
                        # Probably we don't have the commit; fetch it
                        fork([
                            'git', 'fetch', '--depth', '1', 'origin',
                            remote_commit
                        ])
                        # Try again
                        fork(['git', 'checkout', remote_commit, '--'])
                else:
                    fork(['git', 'fetch'])
                    # If we want to go on a branch, try to find a local branch that tracks it
                    # and use it (possibly with a fast-forward)
                    if self.ref_type == 'branch':
                        # Resolve the remote ref
                        remote_fullref = self.symbolic_full_name(self.ref)
                        # Get a sensible local branch name to try
                        local_ref = remote_fullref.split('/origin/', 1)[1]
                        # Check if it is actually tracking our target
                        try:
                            local_fulltrackref = self.symbolic_full_name(
                                local_ref + "@{u}")
                        except CalledProcessError:
                            # It's fine if it fails - we may not have a local-tracking branch,
                            # so git checkout will do the right thing here
                            local_fulltrackref = remote_fullref

                        if remote_fullref == local_fulltrackref:
                            try:
                                # Checkout and fast-forward
                                fork(['git', 'checkout', local_ref, '--'])
                                fork([
                                    'git', 'merge', '--ff-only', self.ref, '--'
                                ])
                                # Final sanity check
                                if log_check_output([
                                        'git', 'rev-parse', self.ref, '--'
                                ]) != log_check_output(
                                    ['git', 'rev-parse', local_ref, '--']):
                                    logger.warning(
                                        "Warning: your local branch is ahead of required remote branch!"
                                    )
                                return
                            except CalledProcessError:
                                logger.warning(
                                    "Couldn't fast-forward local branch, fallback to detached head mode..."
                                )
                    # General case: plain checkout of the origin ref (going in detached HEAD)
                    fork(['git', 'checkout', self.ref, '--'])