Пример #1
0
 def clear(self):
     if os.path.exists('test_diff_command_git_repo_dir'):
         try:
             RmTree('test_diff_command_git_repo_dir')
         except:
             time.sleep(1)
             RmTree('test_diff_command_git_repo_dir')
Пример #2
0
    def testActionDiff(self):
        temp_dir = 'test_diff_command_git_repo_dir'
        git = r'C:\D\bin\git\bin\git.exe'
        if not os.path.exists(git):
            git = 'git'
        self.git = git

        # Test diffing with new folder structure
        subprocess.call([git] + 'init test_diff_command_git_repo_dir'.split(),
                        cwd='.')
        os.mkdir(os.path.join(temp_dir, 'folder1'))
        with open(os.path.join(temp_dir, 'folder1', 'out.txt'), 'w') as f:
            f.write('out')
        called = self.CallDiff()

        self.assertEqual(['winmergeu.exe'], called)

        # Test diffing with previous version of HEAD without changes
        subprocess.call([git] + 'add -A'.split(), cwd=temp_dir)
        subprocess.call([git] + 'commit -m "Second'.split(), cwd=temp_dir)
        called = self.CallDiff()
        self.assertEqual([], called)  #Not called as we don't have any changes.

        # Test diffing with previous version of HEAD^
        def CheckStructure():
            prev = os.path.join('.mu.diff.git.tmp', 'REPO',
                                'test_diff_command_git_repo_dir', 'folder1',
                                'out.txt')
            curr = os.path.join('.mu.diff.git.tmp', 'WORKING',
                                'test_diff_command_git_repo_dir', 'folder1',
                                'out.txt')
            self.assert_(os.path.exists(prev))
            self.assert_(os.path.exists(curr))
            Print('prev', open(prev, 'r').read())
            Print('curr', open(curr, 'r').read())

        with open(os.path.join(temp_dir, 'folder1', 'out.txt'), 'w') as f:
            f.write('new out')
        subprocess.call([git] + 'add -A'.split(), cwd=temp_dir)
        subprocess.call([git] + 'commit -m "Second'.split(), cwd=temp_dir)
        called = self.CallDiff('HEAD^', check_structure=CheckStructure)
        self.assertEqual(['winmergeu.exe'], called)

        # Test diffing dir structure in git changed for file in working dir
        subprocess.call([git] + 'add -A'.split(), cwd=temp_dir)
        subprocess.call([git] + 'commit -m "Third'.split(), cwd=temp_dir)
        RmTree(os.path.join(temp_dir, 'folder1'))
        with open(os.path.join(temp_dir, 'folder1'), 'w') as f:
            f.write('folder1 is now file.')

        called = self.CallDiff()
        self.assertEqual(['winmergeu.exe'], called)

        # Do mu st/mu up just to check if it works.
        from mu_repo.action_default import Run
        config = Config(repos=[temp_dir], git=git)
        Run(Params(config, ['st'], config_file=None))

        import mu_repo
        mu_repo.main(config_file=None, args=['up'])
Пример #3
0
 def symlink(src, target):
     if os.path.isdir(src):
         if os.path.exists(target):
             os.rmdir(target)
         shutil.copytree(src, target)
         keep_files_synched.KeepInSync(src, target)
     else:
         if os.path.exists(target):
             if os.path.isdir(target):
                 RmTree(target)
             else:
                 os.remove(target)
         shutil.copyfile(src, target)
         keep_files_synched.KeepInSync(src, target)
Пример #4
0
 def clear(self):
     if os.path.exists('test_temp_dir'):
         RmTree('test_temp_dir')
Пример #5
0
def test_action_diff():
    temp_dir = 'test_diff_command_git_repo_dir'

    # Test diffing with new folder structure
    subprocess.call([git, 'init', temp_dir], cwd='.')
    configure_git_user(cwd=temp_dir)

    os.mkdir(os.path.join(temp_dir, 'folder1'))
    with open(os.path.join(temp_dir, 'folder1', 'out.txt'), 'w') as f:
        f.write('out')
    called = _call_diff()
    if sys.platform.startswith('win'):
        merge_command = 'winmergeu.exe'
    else:
        merge_command = 'meld'
    assert [merge_command] == called

    # Test diffing with previous version of HEAD without changes
    subprocess.check_call([git] + 'add -A'.split(), cwd=temp_dir)
    subprocess.check_call([git] + 'commit -m "Second'.split(), cwd=temp_dir)
    called = _call_diff()
    assert [] == called  # Not called as we don't have any changes.

    # Test diffing with previous version of HEAD~1
    def check_structure():
        prev = os.path.join('.mu.diff.git.tmp', 'REPO',
                            'test_diff_command_git_repo_dir', 'folder1',
                            'out.txt')
        curr = os.path.join('.mu.diff.git.tmp', 'WORKING',
                            'test_diff_command_git_repo_dir', 'folder1',
                            'out.txt')
        assert os.path.exists(prev)
        assert os.path.exists(curr)
        Print('prev', open(prev, 'r').read())
        Print('curr', open(curr, 'r').read())

    with open(os.path.join(temp_dir, 'folder1', 'out.txt'), 'w') as f:
        f.write('new out')
    subprocess.check_call([git] + 'add -A'.split(), cwd=temp_dir)
    subprocess.check_call([git] + 'commit -m "Second'.split(), cwd=temp_dir)
    called = _call_diff('HEAD~1', check_structure=check_structure)
    assert [merge_command] == called

    # Test diffing dir structure in git changed for file in working dir
    # Nothing changed at this point: newest git now gives a non-zero value in
    # such a case if we try to commit.
    # subprocess.check_call([git] + 'add -A'.split(), cwd=temp_dir)
    # subprocess.check_call([git] + 'commit -m "Third'.split(), cwd=temp_dir)
    RmTree(os.path.join(temp_dir, 'folder1'))
    with open(os.path.join(temp_dir, 'folder1'), 'w') as f:
        f.write('folder1 is now file.')

    called = _call_diff()
    assert [merge_command] == called

    # Do mu st/mu up just to check if it works.
    from mu_repo.action_default import Run
    config = Config(repos=[temp_dir], git=git)
    Run(Params(config, ['st'], config_file=None))

    import mu_repo
    mu_repo.main(config_file=None, args=['up'])
Пример #6
0
def Run(params):
    config = params.config

    join = os.path.join

    temp_dir_name = '.mu.diff.git.tmp'

    if os.path.exists(temp_dir_name):
        n = ''
        while n not in ('y', 'n'):
            n = raw_input(
                'Temporary dir for diff: %s already exists. Delete and continue (y) or cancel (n)? '
                % (temp_dir_name, )).strip().lower()
            if n == 'y':
                RmTree(temp_dir_name)
                break
            if n == 'n':
                Print('Canceling diff action.')
                return

    temp_working = join(temp_dir_name, 'WORKING')
    temp_repo = join(temp_dir_name, 'REPO')
    os.mkdir(temp_dir_name)
    os.mkdir(temp_working)
    os.mkdir(temp_repo)

    from mu_repo import keep_files_synched

    def symlink(src, target):
        if os.path.isdir(src):
            if os.path.exists(target):
                os.rmdir(target)
            shutil.copytree(src, target)
            keep_files_synched.KeepInSync(src, target)
        else:
            if os.path.exists(target):
                if os.path.isdir(target):
                    RmTree(target)
                else:
                    os.remove(target)
            shutil.copyfile(src, target)
            keep_files_synched.KeepInSync(src, target)

    try:
        #Note: we could use diff status --porcelain instead if we wanted to check untracked files.
        #cmd = [git] + 'diff --name-only -z'.split()
        args = params.args
        branch = ''
        repos_and_curr_branch = None
        if len(args) > 1:
            #Ok, the user is comparing current branch with a previous branch or commit.
            #i.e.: mu dd HEAD^^

            branch = args[1]
            if branch == '--prev':
                repos_and_curr_branch = dict(
                    GetReposAndCurrBranch(params, verbose=False))

        threads = []
        for repo in config.repos:
            if repos_and_curr_branch is not None:
                #Note: if --prev is given, it means current_branch@{1}
                #But note that users could also do things as: mu dd master@{10.minutes.ago}
                #References:
                #http://www.kernel.org/pub/software/scm/git/docs/git-rev-parse.html
                #http://stackoverflow.com/questions/1362952/detail-change-after-git-pull
                branch = repos_and_curr_branch[
                    repo] + '@{1}'  #Get the version before the last update.
                thread = DoDiffOnRepoThread(config, repo, symlink,
                                            temp_working, temp_repo, branch)
            else:
                thread = DoDiffOnRepoThread(config, repo, symlink,
                                            temp_working, temp_repo, branch)
            threads.append(thread)
            thread.start()

        for thread in threads:
            thread.join()

        thread_pool.Join()
        for thread in threads:
            if thread.entry_count != 0:
                break
        else:
            Print('No changes found.')
            return

        if sys.platform == 'win32':
            write_left = ['/wl']  #Cannot write on left
            if not branch:
                write_left = [
                ]  #Can write on left when not working with branch (i.e.: working dir).

            winmerge_cmd = 'WinMergeU.exe /r /u /wr /dl WORKINGCOPY /dr HEAD'.split(
            )
            cmd = winmerge_cmd + write_left + [temp_working, temp_repo]
            try:
                subprocess.call(cmd)
            except:
                Print('Error calling: %s' % (' '.join(cmd), ))
        else:
            # Winmerge is not available on Linux, so, let's use another option (meld)
            cmd = ['meld', temp_working, temp_repo]
            try:
                subprocess.call(cmd)
            except:
                Print('Error calling: %s' % (' '.join(cmd), ))

    finally:
        #If we've gone to the synching mode, make sure we had a last synchronization before
        #getting out of the diff.
        if keep_files_synched is not None:
            keep_files_synched.StopSyncs()

        def onerror(*args):
            Print('Error removing temporary directory structure: %s' %
                  (args, ))

        RmTree(temp_dir_name, onerror=onerror)
Пример #7
0
def Run(params):
    config = params.config

    join = os.path.join

    temp_dir_name = '.mu.diff.git.tmp'

    if os.path.exists(temp_dir_name):
        n = ''
        while n not in ('y', 'n'):
            n = raw_input(
                'Temporary dir for diff: %s already exists. Delete and continue (y) or cancel (n)? '
                % (temp_dir_name, )).strip().lower()
            if n == 'y':
                RmTree(temp_dir_name)
                break
            if n == 'n':
                Print('Canceling diff action.')
                return

    temp_working = join(temp_dir_name, 'WORKING')
    temp_repo = join(temp_dir_name, 'REPO')
    os.mkdir(temp_dir_name)
    os.mkdir(temp_working)
    os.mkdir(temp_repo)

    #===============================================================================================
    # Define symlink utility
    #===============================================================================================
    keep_files_synched = None
    try:
        if not hasattr(os, 'symlink'):
            import win32file

            #Note: not all users can do it...
            #http://stackoverflow.com/questions/2094663/determine-if-windows-process-has-privilege-to-create-symbolic-link
            #see: http://bugs.python.org/issue1578269
            #see: http://technet.microsoft.com/en-us/library/cc766301%28WS.10%29.aspx
            def symlink(src, target):
                win32file.CreateSymbolicLink(src, target, 1)
        else:
            symlink = os.symlink

        #Just check if it does indeed work... if it doesn't redefine and use our polling strategy.
        symlink(temp_working, join(temp_dir_name, 'lnk_test'))
    except:
        from mu_repo import keep_files_synched

        def symlink(src, target):
            if os.path.isdir(src):
                if os.path.exists(target):
                    os.rmdir(target)
                shutil.copytree(src, target)
                keep_files_synched.KeepInSync(src, target)
            else:
                if os.path.exists(target):
                    if os.path.isdir(target):
                        RmTree(target)
                    else:
                        os.remove(target)
                shutil.copyfile(src, target)
                keep_files_synched.KeepInSync(src, target)

    try:
        #Note: we could use diff status --porcelain instead if we wanted to check untracked files.
        #cmd = [git] + 'diff --name-only -z'.split()
        args = params.args
        branch = ''
        repos_and_curr_branch = None
        if len(args) > 1:
            #Ok, the user is comparing current branch with a previous branch or commit.
            #i.e.: mu dd HEAD^^

            branch = args[1]
            if branch == '--prev':
                repos_and_curr_branch = dict(
                    GetReposAndCurrBranch(params, verbose=False))

        threads = []
        for repo in config.repos:
            if repos_and_curr_branch is not None:
                #Note: if --prev is given, it means current_branch@{1}
                #But note that users could also do things as: mu dd master@{10.minutes.ago}
                #References:
                #http://www.kernel.org/pub/software/scm/git/docs/git-rev-parse.html
                #http://stackoverflow.com/questions/1362952/detail-change-after-git-pull
                branch = repos_and_curr_branch[
                    repo] + '@{1}'  #Get the version before the last update.
                thread = DoDiffOnRepoThread(config, repo, symlink,
                                            temp_working, temp_repo, branch)
            else:
                thread = DoDiffOnRepoThread(config, repo, symlink,
                                            temp_working, temp_repo, branch)
            threads.append(thread)
            thread.start()

        for thread in threads:
            thread.join()

        thread_pool.Join()
        for thread in threads:
            if thread.entry_count != 0:
                break
        else:
            Print('No changes found.')
            return

        write_left = ['/wl']  #Cannot write on left
        if not branch:
            write_left = [
            ]  #Can write on left when not working with branch (i.e.: working dir).

        winmerge_cmd = 'WinMergeU.exe /r /u /wr /dl WORKINGCOPY /dr HEAD'.split(
        )
        cmd = winmerge_cmd + write_left + [temp_working, temp_repo]
        try:
            subprocess.call(cmd)
        except:
            Print('Error calling: %s' % (' '.join(cmd), ))

    finally:
        #If we've gone to the synching mode, make sure we had a last synchronization before
        #getting out of the diff.
        if keep_files_synched is not None:
            keep_files_synched.StopSyncs()

        def onerror(*args):
            Print('Error removing temporary directory structure: %s' %
                  (args, ))

        RmTree(temp_dir_name, onerror=onerror)