def Restore(repoPath, branchList, transaction):
    print("Restoring state for transaction: {tr}".format(tr=transaction))
    print("branch list:")
    for br in branchList:
        print("  - Branch {br} at {hash}.{current}".format(br=br["name"], hash=br["commit"], current=' Current.' if br["is_current"] else ''))

    state = { "transaction": transaction, "branch_list": branchList }

    repo = git.open(repoPath)
    if repo is None:
        print("Failed to open git repository '{r}'".format(r=repoPath))
        return 1

    stateFilePath = None
    with tempfile.NamedTemporaryFile(mode='w+', prefix='ac2git_state_', delete=False) as stateFile:
        stateFilePath = stateFile.name
        stateFile.write(json.dumps(state))

    hashObj = repo.raw_cmd(['git', 'hash-object', '-w', stateFilePath ])
    if hashObj is None:
        raise Exception("Failed to restore state! git hash-object -w {f}, returned {r}.".format(f=stateFilePath, r=hashObj))
    else:
        os.remove(stateFilePath)

    refResult = repo.raw_cmd(['git', 'update-ref', 'refs/ac2git/state', hashObj])
    if refResult is None:
        raise Exception("Failed to restore state! git update-ref refs/ac2git/state {h}, returned {r}.".format(h=hashObj, r=refResult))
    
    return 0
Example #2
0
def GetBranchRevisionMap(gitRepoPath):
    # 1. Compare all of the different branch's commit timestamps.
    # 2. Select the earliest commit and iterate over commits (from all branches).
    # 3. Store each processed commit hash against the hash of the "tree" object to which it
    #    points. You can get the tree hashes via the `git cat-file -p <commit-hash>` command.
    # 4. When processing any new commit, look up to see if the tree object has already been
    #    cataloged in step 3.
    #      YES -> Figure out if it makes sense for these branches to be stitched together.
    #             It is recommended that you consider the committer, the commit time, the author
    #             and the author time of each commit.
    #      NO  -> Continue.

    if git.isRepo(gitRepoPath):
        repo = git.open(gitRepoPath)
        branchList = repo.branch_list()
        branchRevMap = {}

        # For each branch in the branch list get the commit history which doesn't share
        # ancestry with any other branch.
        # See 'git rev-list'
        # Example command:
        #   git rev-list --reverse my-branch ^other-branch ^another-branch
        for current_branch in branchList:
            # Get the commits that are only on this branch.
            revListArgs = [ current_branch.name ]
            for other_branch in branchList:
                if current_branch != other_branch:
                    revListArgs.append('^{0}'.format(other_branch.name))

            git_cmd = u'git rev-list --reverse'
            for arg in revListArgs:
                git_cmd = u'{0} {1}'.format(git_cmd, arg)
            
            cmd = git_cmd.split()
            try:
              revlist = subprocess.check_output(cmd).decode('utf8', 'strict')
            except subprocess.CalledProcessError as e:
              print(u'Failed to execute command: {0}'.format(git_cmd))
              raise e

            #print(u'Executed: {0}'.format(git_cmd))
            revlist = revlist.split()

            # For each of the commits returned by the git rev-list command get the tree hash
            # to which they point and store it in a map against the tree hash.
            # For each commit map it to its tree by using the git cat-file command.
            for rev in revlist:
                commit_info = CatFileCommit(rev)
                commit_info[u'branch'] = current_branch
                tree_hash = commit_info[u'object'][u'hash']
                
                #print(u'commit: {0}, tree: {1}, branch: {2}'.format(rev, tree_hash, current_branch.name))
                
                if not tree_hash in branchRevMap:
                    branchRevMap[tree_hash] = []
                branchRevMap[tree_hash].append(commit_info)

        return branchRevMap
    return None
Example #3
0
def GetBranchRevisionMap(gitRepoPath):
    # 1. Compare all of the different branch's commit timestamps.
    # 2. Select the earliest commit and iterate over commits (from all branches).
    # 3. Store each processed commit hash against the hash of the "tree" object to which it
    #    points. You can get the tree hashes via the `git cat-file -p <commit-hash>` command.
    # 4. When processing any new commit, look up to see if the tree object has already been
    #    cataloged in step 3.
    #      YES -> Figure out if it makes sense for these branches to be stitched together.
    #             It is recommended that you consider the committer, the commit time, the author
    #             and the author time of each commit.
    #      NO  -> Continue.

    if git.isRepo(gitRepoPath):
        repo = git.open(gitRepoPath)
        branchList = repo.branch_list()
        branchRevMap = {}

        # For each branch in the branch list get the commit history which doesn't share
        # ancestry with any other branch.
        # See 'git rev-list'
        # Example command:
        #   git rev-list --reverse my-branch ^other-branch ^another-branch
        for current_branch in branchList:
            # Get the commits that are only on this branch.
            revListArgs = [current_branch.name]
            for other_branch in branchList:
                if current_branch != other_branch:
                    revListArgs.append('^{0}'.format(other_branch.name))

            git_cmd = u'git rev-list --reverse'
            for arg in revListArgs:
                git_cmd = u'{0} {1}'.format(git_cmd, arg)

            cmd = git_cmd.split()
            try:
                revlist = subprocess.check_output(git.to_utf8(c) for c in cmd)
            except subprocess.CalledProcessError as e:
                print(u'Failed to execute command: {0}'.format(git_cmd))
                raise e

            #print(u'Executed: {0}'.format(git_cmd))
            revlist = revlist.split()

            # For each of the commits returned by the git rev-list command get the tree hash
            # to which they point and store it in a map against the tree hash.
            # For each commit map it to its tree by using the git cat-file command.
            for rev in revlist:
                commit_info = CatFileCommit(rev)
                commit_info[u'branch'] = current_branch
                tree_hash = commit_info[u'object'][u'hash']

                #print(u'commit: {0}, tree: {1}, branch: {2}'.format(rev, tree_hash, current_branch.name))

                if not branchRevMap.has_key(tree_hash):
                    branchRevMap[tree_hash] = []
                branchRevMap[tree_hash].append(commit_info)

        return branchRevMap
    return None
Example #4
0
def Restore(repoPath, branchList, transaction):
    print("Restoring state for transaction: {tr}".format(tr=transaction))
    print("branch list:")
    for br in branchList:
        print("  - Branch {br} at {hash}.{current}".format(
            br=br["name"],
            hash=br["commit"],
            current=' Current.' if br["is_current"] else ''))

    state = {"transaction": transaction, "branch_list": branchList}

    repo = git.open(repoPath)
    if repo is None:
        print("Failed to open git repository '{r}'".format(r=repoPath))
        return 1

    stateFilePath = None
    with tempfile.NamedTemporaryFile(mode='w+',
                                     prefix='ac2git_state_',
                                     delete=False) as stateFile:
        stateFilePath = stateFile.name
        stateFile.write(json.dumps(state))

    hashObj = repo.raw_cmd(['git', 'hash-object', '-w', stateFilePath])
    if hashObj is None:
        raise Exception(
            "Failed to restore state! git hash-object -w {f}, returned {r}.".
            format(f=stateFilePath, r=hashObj))
    else:
        os.remove(stateFilePath)

    refResult = repo.raw_cmd(
        ['git', 'update-ref', 'refs/ac2git/state', hashObj])
    if refResult is None:
        raise Exception(
            "Failed to restore state! git update-ref refs/ac2git/state {h}, returned {r}."
            .format(h=hashObj, r=refResult))

    return 0