def test_checkout_specific_branch_and_update(self): # subdir = "checkout_specific_version_test" url = self.remote_path branch = "test_branch" client = GitClient(self.local_path) self.assertFalse(client.path_exists()) self.assertFalse(client.detect_presence()) self.assertTrue(client.checkout(url, branch)) self.assertTrue(client.path_exists()) self.assertTrue(client.detect_presence()) self.assertTrue(client.is_local_branch(branch)) self.assertEqual(client.get_path(), self.local_path) self.assertEqual(client.get_url(), url) self.assertEqual(client.get_version(), self.readonly_version_init) self.assertEqual(client.get_branch(), branch) self.assertEqual(client.get_branch_parent(), branch) self.assertTrue(client.update()) # no arg self.assertEqual(client.get_branch(), branch) self.assertEqual(client.get_version(), self.readonly_version_init) self.assertEqual(client.get_branch_parent(), branch) self.assertTrue(client.update(branch)) # same branch arg self.assertEqual(client.get_branch(), branch) self.assertEqual(client.get_version(), self.readonly_version_init) self.assertEqual(client.get_branch_parent(), branch) new_branch = 'master' self.assertTrue(client.update(new_branch)) self.assertEqual(client.get_branch(), new_branch) self.assertEqual(client.get_branch_parent(), new_branch)
def test_detached_to_branch(self): client = GitClient(self.local_path) # url = self.remote_path self.assertEqual(client.get_branch(), "master") tag = "no_br_tag" self.assertTrue(client.update(tag)) self.assertEqual(client.get_branch(), None) self.assertEqual(client.get_branch_parent(), None) tag = "test_tag" self.assertTrue(client.update(tag)) self.assertEqual(client.get_branch(), None) self.assertEqual(client.get_version(), self.readonly_version_init) self.assertEqual(client.get_branch_parent(), None) #update should not change anything self.assertTrue(client.update()) # no arg self.assertEqual(client.get_branch(), None) self.assertEqual(client.get_version(), self.readonly_version_init) self.assertEqual(client.get_branch_parent(), None) new_branch = 'master' self.assertTrue(client.update(new_branch)) self.assertEqual(client.get_branch(), new_branch) self.assertEqual(client.get_version(), self.readonly_version) self.assertEqual(client.get_branch_parent(), new_branch)
def test_checkout_specific_branch_and_update(self): # subdir = "checkout_specific_version_test" url = self.remote_path branch = "test_branch" client = GitClient(self.local_path) self.assertFalse(client.path_exists()) self.assertFalse(client.detect_presence()) self.assertTrue(client.checkout(url, branch)) self.assertTrue(client.path_exists()) self.assertTrue(client.detect_presence()) self.assertTrue(client._is_local_branch(branch)) self.assertEqual(client.get_path(), self.local_path) self.assertEqual(client.get_url(), url) self.assertEqual(client.get_version(), self.readonly_version_init) self.assertEqual(client._get_branch(), branch) self.assertEqual(client._get_branch_parent(), (branch, "origin")) self.assertTrue(client.update()) # no arg self.assertEqual(client._get_branch(), branch) self.assertEqual(client.get_version(), self.readonly_version_init) self.assertEqual(client._get_branch_parent(), (branch, "origin")) self.assertTrue(client.update(branch)) # same branch arg self.assertEqual(client._get_branch(), branch) self.assertEqual(client.get_version(), self.readonly_version_init) self.assertEqual(client._get_branch_parent(), (branch, "origin")) new_branch = 'master' self.assertTrue(client.update(new_branch)) self.assertEqual(client._get_branch(), new_branch) self.assertEqual(client._get_branch_parent(), (new_branch, "origin"))
def test_detached_to_branch(self): client = GitClient(self.local_path) # url = self.remote_path self.assertEqual(client._get_branch(), "master") tag = "no_br_tag" self.assertTrue(client.update(tag)) self.assertEqual(client._get_branch(), None) self.assertEqual(client._get_branch_parent(), (None, None)) tag = "test_tag" self.assertTrue(client.update(tag)) self.assertEqual(client._get_branch(), None) self.assertEqual(client.get_version(), self.readonly_version_init) self.assertEqual(client._get_branch_parent(), (None, None)) #update should not change anything self.assertTrue(client.update()) # no arg self.assertEqual(client._get_branch(), None) self.assertEqual(client.get_version(), self.readonly_version_init) self.assertEqual(client._get_branch_parent(), (None, None)) new_branch = 'master' self.assertTrue(client.update(new_branch)) self.assertEqual(client._get_branch(), new_branch) self.assertEqual(client.get_version(), self.readonly_version) self.assertEqual(client._get_branch_parent(), (new_branch, "origin"))
def test_get_branch_parent(self): client = GitClient(path=self.local_path) client.checkout(url=self.remote_path, version='master') self.assertEqual(client._get_branch_parent(), ("master", "origin")) # with other remote than origin for cmd in ['git remote add remote2 %s' % self.remote_path, 'git config --replace-all branch.master.remote remote2']: subprocess.check_call(cmd, shell=True, cwd=self.local_path) self.assertEqual(client._get_branch_parent(), (None, None)) self.assertEqual(client._get_branch_parent(fetch=True), ('master', "remote2")) # with not actual remote branch cmd = 'git config --replace-all branch.master.merge dummy_branch' subprocess.check_call(cmd, shell=True, cwd=self.local_path) self.assertEqual(client._get_branch_parent(), (None, None)) # return remote back to original config for cmd in [ 'git config --replace-all branch.master.remote origin', 'git config --replace-all branch.master.merge refs/heads/master']: subprocess.check_call(cmd, shell=True, cwd=self.local_path) # with detached local status client.update(version='test_tag') self.assertEqual(client._get_branch_parent(), (None, None)) # back to master branch client.update(version='master')
def test_get_current_version_label(self): client = GitClient(path=self.local_path) # with detached local status client.checkout(url=self.remote_path, version='test_tag') self.assertEqual(client.get_current_version_label(), '<detached>') # when difference between local and tracking branch client.update(version='master') self.assertEqual(client.get_current_version_label(), 'master') # with other tracking branch cmd = 'git config --replace-all branch.master.merge test_branch' subprocess.check_call(cmd, shell=True, cwd=self.local_path) self.assertEqual(client.get_current_version_label(), 'master < test_branch') # with other remote for cmd in [ 'git remote add remote2 %s' % self.remote_path, 'git config --replace-all branch.master.remote remote2', 'git fetch remote2']: subprocess.check_call(cmd, shell=True, cwd=self.local_path) self.assertEqual(client.get_current_version_label(), 'master < remote2/test_branch') # return remote back to original config for cmd in [ 'git config --replace-all branch.master.remote origin', 'git config --replace-all branch.master.merge refs/heads/master']: subprocess.check_call(cmd, shell=True, cwd=self.local_path)
def test_fast_forward(self): url = self.remote_path client = GitClient(self.local_path) self.assertTrue(client.checkout(url, "master")) subprocess.check_call("git reset --hard test_tag", shell=True, cwd=self.local_path) self.assertTrue(client.update())
def test_fast_forward_diverged(self): url = self.remote_path client = GitClient(self.local_path) self.assertTrue(client.checkout(url, "master")) subprocess.check_call("git reset --hard test_tag", shell=True, cwd=self.local_path) subprocess.check_call("touch diverged.txt", shell=True, cwd=self.local_path) subprocess.check_call("git add *", shell=True, cwd=self.local_path) subprocess.check_call("git commit -m diverge", shell=True, cwd=self.local_path) # fail because we have diverged self.assertFalse(client.update('master'))
def test_checkout_specific_tag_and_update(self): url = self.remote_path tag = "last_tag" client = GitClient(self.local_path) self.assertFalse(client.path_exists()) self.assertFalse(client.detect_presence()) self.assertTrue(client.checkout(url, tag)) self.assertTrue(client.path_exists()) self.assertTrue(client.detect_presence()) self.assertEqual(client.get_path(), self.local_path) self.assertEqual(client.get_url(), url) self.assertEqual(client.get_branch_parent(), None) tag = "test_tag" self.assertTrue(client.update(tag)) self.assertEqual(client.get_branch_parent(), None) new_branch = 'master' self.assertTrue(client.update(new_branch)) self.assertEqual(client.get_branch_parent(), new_branch) tag = "test_tag" self.assertTrue(client.update(tag))
def test_checkout_specific_tag_and_update(self): url = self.remote_path tag = "last_tag" client = GitClient(self.local_path) self.assertFalse(client.path_exists()) self.assertFalse(client.detect_presence()) self.assertTrue(client.checkout(url, tag)) self.assertTrue(client.path_exists()) self.assertTrue(client.detect_presence()) self.assertEqual(client.get_path(), self.local_path) self.assertEqual(client.get_url(), url) self.assertEqual(client._get_branch_parent(), (None, None)) tag = "test_tag" self.assertTrue(client.update(tag)) self.assertEqual(client._get_branch_parent(), (None, None)) new_branch = 'master' self.assertTrue(client.update(new_branch)) self.assertEqual(client._get_branch_parent(), (new_branch, "origin")) tag = "test_tag" self.assertTrue(client.update(tag))
def test_checkout_no_unnecessary_updates(self): client = GitClient(self.local_path) client.fetches = 0 client.submodules = 0 client.fast_forwards = 0 def ifetch(self): self.fetches += 1 return True def iff(self, fetch=True, branch_parent=None, verbose=False): self.fast_forwards += 1 return True def isubm(self, verbose=False, timeout=None): self.submodules += 1 return True client._do_fetch = types.MethodType(ifetch, client) client._do_fast_forward = types.MethodType(iff, client) client.update_submodules = types.MethodType(isubm, client) url = self.remote_path self.assertFalse(client.path_exists()) self.assertFalse(client.detect_presence()) self.assertTrue(client.checkout(url)) self.assertEqual(0, client.submodules) self.assertEqual(0, client.fetches) self.assertEqual(0, client.fast_forwards) self.assertTrue(client.update()) self.assertEqual(1, client.submodules) self.assertEqual(1, client.fetches) self.assertEqual(1, client.fast_forwards) self.assertTrue(client.update('test_branch')) self.assertEqual(2, client.submodules) self.assertEqual(2, client.fetches) self.assertEqual(1, client.fast_forwards) self.assertTrue(client.update('test_branch')) self.assertEqual(3, client.submodules) self.assertEqual(3, client.fetches) self.assertEqual(2, client.fast_forwards)
def test_checkout_no_unnecessary_updates(self): client = GitClient(self.local_path) client.fetches = 0 client.submodules = 0 client.fast_forwards = 0 def ifetch(self): self.fetches += 1 return True def iff(self, branch_parent, fetch=True, verbose=False): self.fast_forwards += 1 return True def isubm(self, verbose=False, timeout=None): self.submodules += 1 return True client._do_fetch = types.MethodType(ifetch, client) client._do_fast_forward = types.MethodType(iff, client) client._update_submodules = types.MethodType(isubm, client) url = self.remote_path self.assertFalse(client.path_exists()) self.assertFalse(client.detect_presence()) self.assertTrue(client.checkout(url)) self.assertEqual(0, client.submodules) self.assertEqual(0, client.fetches) self.assertEqual(0, client.fast_forwards) self.assertTrue(client.update()) self.assertEqual(1, client.submodules) self.assertEqual(1, client.fetches) self.assertEqual(1, client.fast_forwards) self.assertTrue(client.update('test_branch')) self.assertEqual(2, client.submodules) self.assertEqual(2, client.fetches) self.assertEqual(1, client.fast_forwards) self.assertTrue(client.update('test_branch')) self.assertEqual(3, client.submodules) self.assertEqual(3, client.fetches) self.assertEqual(2, client.fast_forwards)
def test_update_fetch_all_tags(self): url = self.remote_path client = GitClient(self.local_path) self.assertTrue(client.checkout(url, "master")) self.assertEqual(client.get_branch(), "master") self.assertTrue(client.update()) p = subprocess.Popen("git tag", shell=True, cwd=self.local_path, stdout=subprocess.PIPE) output = p.communicate()[0].decode('utf-8') self.assertEqual('last_tag\ntest_tag\n', output) subprocess.check_call("git checkout test_tag", shell=True, cwd=self.remote_path) subprocess.check_call("git branch alt_branch", shell=True, cwd=self.remote_path) subprocess.check_call("touch alt_file.txt", shell=True, cwd=self.remote_path) subprocess.check_call("git add *", shell=True, cwd=self.remote_path) subprocess.check_call("git commit -m altfile", shell=True, cwd=self.remote_path) # switch to untracked subprocess.check_call("git checkout test_tag", shell=True, cwd=self.remote_path) subprocess.check_call("touch new_file.txt", shell=True, cwd=self.remote_path) subprocess.check_call("git add *", shell=True, cwd=self.remote_path) subprocess.check_call("git commit -m newfile", shell=True, cwd=self.remote_path) subprocess.check_call("git tag new_tag", shell=True, cwd=self.remote_path) self.assertTrue(client.update()) # test whether client gets the tag p = subprocess.Popen("git tag", shell=True, cwd=self.local_path, stdout=subprocess.PIPE) output = p.communicate()[0].decode('utf-8') self.assertEqual('''\ last_tag new_tag test_tag ''', output) p = subprocess.Popen("git branch -a", shell=True, cwd=self.local_path, stdout=subprocess.PIPE) output = p.communicate()[0].decode('utf-8') self.assertEqual('''\ * master remotes/origin/HEAD -> origin/master remotes/origin/alt_branch remotes/origin/master remotes/origin/test_branch ''', output)
def test_update_fetch_all_tags(self): url = self.remote_path client = GitClient(self.local_path) self.assertTrue(client.checkout(url, "master")) self.assertEqual(client._get_branch(), "master") self.assertTrue(client.update()) p = subprocess.Popen("git tag", shell=True, cwd=self.local_path, stdout=subprocess.PIPE) output = p.communicate()[0].decode('utf-8') self.assertEqual('last_tag\ntest_tag\n', output) subprocess.check_call("git checkout test_tag", shell=True, cwd=self.remote_path) subprocess.check_call("git branch alt_branch", shell=True, cwd=self.remote_path) subprocess.check_call("touch alt_file.txt", shell=True, cwd=self.remote_path) subprocess.check_call("git add *", shell=True, cwd=self.remote_path) subprocess.check_call("git commit -m altfile", shell=True, cwd=self.remote_path) # switch to untracked subprocess.check_call("git checkout test_tag", shell=True, cwd=self.remote_path) subprocess.check_call("touch new_file.txt", shell=True, cwd=self.remote_path) subprocess.check_call("git add *", shell=True, cwd=self.remote_path) subprocess.check_call("git commit -m newfile", shell=True, cwd=self.remote_path) subprocess.check_call("git tag new_tag", shell=True, cwd=self.remote_path) self.assertTrue(client.update()) # test whether client gets the tag p = subprocess.Popen("git tag", shell=True, cwd=self.local_path, stdout=subprocess.PIPE) output = p.communicate()[0].decode('utf-8') self.assertEqual('''\ last_tag new_tag test_tag ''', output) p = subprocess.Popen("git branch -a", shell=True, cwd=self.local_path, stdout=subprocess.PIPE) output = p.communicate()[0].decode('utf-8') self.assertEqual('''\ * master remotes/origin/HEAD -> origin/master remotes/origin/alt_branch remotes/origin/master remotes/origin/test_branch ''', output)
def test_protect_dangling(self): client = GitClient(self.local_path) # url = self.remote_path self.assertEqual(client._get_branch(), "master") tag = "no_br_tag" self.assertTrue(client.update(tag)) self.assertEqual(client._get_branch(), None) self.assertEqual(client._get_branch_parent(), (None, None)) tag = "test_tag" self.assertTrue(client.update(tag)) self.assertEqual(client._get_branch(), None) self.assertEqual(client._get_branch_parent(), (None, None)) # to dangling commit sha = self.dangling_version self.assertTrue(client.update(sha)) self.assertEqual(client._get_branch(), None) self.assertEqual(client.get_version(), self.dangling_version) self.assertEqual(client._get_branch_parent(), (None, None)) # now HEAD protects the dangling commit, should not be allowed to move off. new_branch = 'master' self.assertFalse(client.update(new_branch))
def test_protect_dangling(self): client = GitClient(self.local_path) # url = self.remote_path self.assertEqual(client.get_branch(), "master") tag = "no_br_tag" self.assertTrue(client.update(tag)) self.assertEqual(client.get_branch(), None) self.assertEqual(client.get_branch_parent(), None) tag = "test_tag" self.assertTrue(client.update(tag)) self.assertEqual(client.get_branch(), None) self.assertEqual(client.get_branch_parent(), None) # to dangling commit sha = self.dangling_version self.assertTrue(client.update(sha)) self.assertEqual(client.get_branch(), None) self.assertEqual(client.get_version(), self.dangling_version) self.assertEqual(client.get_branch_parent(), None) # now HEAD protects the dangling commit, should not be allowed to move off. new_branch = 'master' self.assertFalse(client.update(new_branch))
def test_checkout_untracked_branch_and_update(self): # difference to tracked branches is that branch parent is None, and we may hop outside lineage client = GitClient(self.local_path) url = self.remote_path branch = "localbranch" self.assertEqual(client.get_branch(), "master") self.assertTrue(client.path_exists()) self.assertTrue(client.detect_presence()) self.assertTrue(client.is_local_branch(branch)) self.assertEqual(client.get_path(), self.local_path) self.assertEqual(client.get_url(), url) self.assertTrue(client.update(branch)) self.assertEqual(client.get_version(), self.untracked_version) self.assertEqual(client.get_branch(), branch) self.assertEqual(client.get_branch_parent(), None) self.assertTrue(client.update()) # no arg self.assertEqual(client.get_branch(), branch) self.assertEqual(client.get_version(), self.untracked_version) self.assertEqual(client.get_branch_parent(), None) self.assertTrue(client.update(branch)) # same branch arg self.assertEqual(client.get_branch(), branch) self.assertEqual(client.get_version(), self.untracked_version) self.assertEqual(client.get_branch_parent(), None) # to master new_branch = 'master' self.assertTrue(client.update(new_branch)) self.assertEqual(client.get_branch(), new_branch) self.assertEqual(client.get_version(), self.readonly_version) self.assertEqual(client.get_branch_parent(), new_branch) # and back self.assertTrue(client.update(branch)) # same branch arg self.assertEqual(client.get_branch(), branch) self.assertEqual(client.get_version(), self.untracked_version) self.assertEqual(client.get_branch_parent(), None) # to dangling commit sha = self.dangling_version self.assertTrue(client.update(sha)) self.assertEqual(client.get_branch(), None) self.assertEqual(client.get_version(), self.dangling_version) self.assertEqual(client.get_branch_parent(), None) #should not work to protect commits from becoming dangled # to commit outside lineage tag = "test_tag" self.assertFalse(client.update(tag))
def test_checkout_specific_version_and_update(self): url = self.remote_path version = self.readonly_version client = GitClient(self.local_path) self.assertFalse(client.path_exists()) self.assertFalse(client.detect_presence()) self.assertTrue(client.checkout(url, version)) self.assertTrue(client.path_exists()) self.assertTrue(client.detect_presence()) self.assertEqual(client.get_path(), self.local_path) self.assertEqual(client.get_url(), url) self.assertEqual(client.get_version(), version) new_version = self.readonly_version_second self.assertTrue(client.update(new_version)) self.assertEqual(client.get_version(), new_version)
def test_checkout_master_branch_and_update(self): # subdir = "checkout_specific_version_test" url = self.remote_path branch = "master" client = GitClient(self.local_path) self.assertFalse(client.path_exists()) self.assertFalse(client.detect_presence()) self.assertTrue(client.checkout(url, branch)) self.assertTrue(client.path_exists()) self.assertTrue(client.detect_presence()) self.assertEqual(client.get_path(), self.local_path) self.assertEqual(client.get_url(), url) self.assertEqual(client.get_branch_parent(), branch) self.assertTrue(client.update(branch)) self.assertEqual(client.get_branch_parent(), branch)
def test_checkout_untracked_branch_and_update(self): # difference to tracked branches is that branch parent is None, and we may hop outside lineage client = GitClient(self.local_path) url = self.remote_path branch = "localbranch" self.assertEqual(client._get_branch(), "master") self.assertTrue(client.path_exists()) self.assertTrue(client.detect_presence()) self.assertTrue(client._is_local_branch(branch)) self.assertEqual(client.get_path(), self.local_path) self.assertEqual(client.get_url(), url) self.assertTrue(client.update(branch)) self.assertEqual(client.get_version(), self.untracked_version) self.assertEqual(client._get_branch(), branch) self.assertEqual(client._get_branch_parent(), (None, None)) self.assertTrue(client.update()) # no arg self.assertEqual(client._get_branch(), branch) self.assertEqual(client.get_version(), self.untracked_version) self.assertEqual(client._get_branch_parent(), (None, None)) self.assertTrue(client.update(branch)) # same branch arg self.assertEqual(client._get_branch(), branch) self.assertEqual(client.get_version(), self.untracked_version) self.assertEqual(client._get_branch_parent(), (None, None)) # to master new_branch = 'master' self.assertTrue(client.update(new_branch)) self.assertEqual(client._get_branch(), new_branch) self.assertEqual(client.get_version(), self.readonly_version) self.assertEqual(client._get_branch_parent(), (new_branch, "origin")) # and back self.assertTrue(client.update(branch)) # same branch arg self.assertEqual(client._get_branch(), branch) self.assertEqual(client.get_version(), self.untracked_version) self.assertEqual(client._get_branch_parent(), (None, None)) # to dangling commit sha = self.dangling_version self.assertTrue(client.update(sha)) self.assertEqual(client._get_branch(), None) self.assertEqual(client.get_version(), self.dangling_version) self.assertEqual(client._get_branch_parent(), (None, None)) #should not work to protect commits from becoming dangled # to commit outside lineage tag = "test_tag" self.assertFalse(client.update(tag))
def test_checkout_master_branch_and_update(self): # subdir = "checkout_specific_version_test" url = self.remote_path branch = "master" client = GitClient(self.local_path) self.assertFalse(client.path_exists()) self.assertFalse(client.detect_presence()) self.assertTrue(client.checkout(url, branch)) self.assertTrue(client.path_exists()) self.assertTrue(client.detect_presence()) self.assertEqual(client.get_path(), self.local_path) self.assertEqual(client.get_url(), url) self.assertEqual(client._get_branch_parent(), (branch, "origin")) self.assertTrue(client.update(branch)) self.assertEqual(client._get_branch_parent(), (branch, "origin"))
def test_checkout_local_only_branch_and_update(self): # prevent regression on wstool#25: no rebase after switching branch url = self.remote_path branch = "master" client = GitClient(self.local_path) self.assertFalse(client.path_exists()) self.assertFalse(client.detect_presence()) self.assertTrue(client.checkout(url, branch)) self.assertTrue(client.path_exists()) self.assertTrue(client.detect_presence()) self.assertTrue(client._is_local_branch(branch)) subprocess.check_call("git reset --hard HEAD~1", shell=True, cwd=self.local_path) subprocess.check_call("git checkout -b new_local_branch", shell=True, cwd=self.local_path) self.assertTrue(client.update(branch)) # same branch arg self.assertEqual(client._get_branch(), branch) self.assertEqual(client.get_version(), self.readonly_version) self.assertEqual(client._get_branch_parent(), (branch, "origin"))
def test_get_remote_version(self): url = self.remote_path client = GitClient(path=self.local_path) client.checkout(url, version='master') self.assertEqual(client.get_remote_version(fetch=True), self.readonly_version) self.assertEqual(client.get_remote_version(fetch=False), self.readonly_version) subprocess.check_call("git reset --hard test_tag", shell=True, cwd=self.local_path) self.assertEqual(client.get_remote_version(fetch=True), self.readonly_version) client.update(version='test_branch') self.assertEqual(client.get_remote_version(fetch=True), self.readonly_version_init) client.update(version='test_branch') self.assertEqual(client.get_remote_version(fetch=False), self.readonly_version_init) # switch tracked branch subprocess.check_call('git config --replace-all branch.master.merge test_branch', shell=True, cwd=self.local_path) client.update(version='master') self.assertEqual(client.get_remote_version(fetch=False), self.readonly_version_init) # with other remote for cmd in [ 'git remote add remote2 %s' % self.remote_path, 'git config --replace-all branch.master.remote remote2', 'git fetch remote2']: subprocess.check_call(cmd, shell=True, cwd=self.local_path) self.assertEqual(client.get_remote_version(fetch=False), self.readonly_version_init)