def __init__(self, authorized_dates, authorized_hours=DEFAULT_AUTHORIZED_HOURS, authorized_weekdays=DEFAULT_AUTHORIZED_WEEKDAYS): """ Simulates a continuous timelapse out of hours, dates and weekdays limits. :param min_date: datetime object describing the min authorized date :param max_date: datetime object describing the max authorized date :param authorized_hours: tuple containing 2-tuples of the limits of the authorized time ranges :param authorized_weekdays: tuple containing the authorized weekdays, described by their number in a week starting by monday -> 1. """ self.authorized_ranges = {} self.total_days = 0 self.total_seconds = 0 min_date, max_date = authorized_dates days_lapse = (max_date - min_date).days cur_date = min_date while cur_date != max_date: if cur_date.weekday() in authorized_weekdays: self.total_days += 1 for time_min, time_max in authorized_hours: down_limit = datetime(cur_date.year, cur_date.month, cur_date.day, time_min.hour, time_min.minute, time_min.second, time_min.microsecond) up_limit = datetime(cur_date.year, cur_date.month, cur_date.day, time_max.hour, time_max.minute, time_max.second, time_max.microsecond) delta = (up_limit - down_limit) self.authorized_ranges[self.total_seconds] = (down_limit, up_limit) self.total_seconds += delta.seconds cur_date += timedelta(1) if not self.authorized_ranges: raise GfbiException("The non-continuous timelapse is empty.")
def is_deleted(self, indexorcommit): """ If indexorcommit: * is an index, if the commit at index.row() is a deleted commit, return True. * is a commit, if the commit is a deleted commit, return True. """ if hasattr(indexorcommit, 'row'): if not 0 <= indexorcommit.row() < len(self._commits): raise GfbiException("Invalid index") commit = self._commits[indexorcommit.row()] else: commit = indexorcommit return commit in self._deleted_commits
def set_data(self, index, value, ignore_history=False): """ Set the given value to the commit and the field determined by the index. :param index: The index of the commit and the field that should be modified. :param value: The value that will be assigned. """ if not 0 <= index.row() < len(self._commits): raise GfbiException("Invalid index") commit = self._commits[index.row()] column = index.column() field_name = self._columns[column] reference = None if field_name in TIME_FIELDS: if self.data(index) is not None: reference, tz = self.data(index) else: reference = self.data(index) # This is useless in the development version of GitPython # See https://github.com/gitpython-developers/GitPython/commit/096897123ab5d8b500024e63ca81b658f3cb93da git_python_precheck = (hasattr(reference, 'binsha') != hasattr( value, 'binsha')) if git_python_precheck or reference != value: self.set_field_data(commit, field_name, value) if not ignore_history: action = SetAction(index, reference, value) self._history[self._last_history_event].append(action) if self._merge: if field_name == "committed_date": self.set_field_data(commit, "authored_date", value) elif field_name == "authored_date": self.set_field_data(commit, "committed_date", value) elif field_name == "author_name": self.set_field_data(commit, "committer_name", value) elif field_name == "committer_name": self.set_field_data(commit, "author_name", value) elif field_name == "author_email": self.set_field_data(commit, "committer_email", value) elif field_name == "committer_email": self.set_field_data(commit, "author_email", value)
def __init__(self, directory=".", fake_branch_name="", from_commits=False, remote_ref=None): """ Initializes the model with the repository root directory. :param directory: Root directory of the git repository. """ self._directory = directory self._remote_ref = False self._current_branch = None if fake_branch_name: # This is an empy gitModel that will be filled with data from # another model self._repo = None self._current_branch = DummyBranch(fake_branch_name) if not from_commits: raise GfbiException("Can't build a fake model without commits") self._from_commits = from_commits elif remote_ref: # This is a model on a remote repository self._repo = Repo(directory) self._remote_ref = remote_ref self._current_branch = False else: self._repo = Repo(directory) self._current_branch = self._repo.active_branch self._columns = [ 'hexsha', 'authored_date', 'committed_date', 'author_name', 'author_email', 'committer_name', 'committer_email', 'message', 'parents', 'tree', 'children' ] self._changed_branch_once = False self._commits = [] self._unpushed = [] self._children = {} self._old_branch_name = ""
def set_current_branch(self, branch, force=False): """ Sets the model's current branch. :param branch: The desired branch to modelize. """ if self._changed_branch_once and not force: raise GfbiException("You shouldn't change the branch twice.") if self.is_fake_model(): # This is the moment after we wrote the model, the model is getting # real (not fake). self.orig_model = GitModel(directory=self._directory) self.orig_model.set_current_branch(branch, force=force) self._modifications = {} GitModel.set_current_branch(self, branch, force=force)
def populate(self): """ Populates the model, by constructing a list of the commits of the current branch of the given repository. """ if self.is_fake_model(): if not self._from_commits: error = "This is a fake model, but we don't have commits to build it." raise GfbiException(error) self._commits = list(self._from_commits) return self._commits = [] self._unpushed = [] self._children = {} if self._remote_ref: branch_rev = self._remote_ref.commit else: branch_rev = self._current_branch.commit if self._current_branch and self._current_branch.tracking_branch(): remote_commits_head = self._current_branch.tracking_branch().commit else: remote_commits_head = None pushed = False for commit in self._repo.iter_commits(rev=branch_rev): self._commits.append(commit) for parent in commit.parents: if parent not in self._children: self._children[parent] = [ commit, ] else: self._children[parent].append(commit) if remote_commits_head is not None and \ commit.hexsha == remote_commits_head.hexsha: pushed = True if not pushed: self._unpushed.append(commit)
def set_current_branch(self, branch, force=False): """ Sets the model's current branch. As populate() is costly, we don't do it automaticaly here. :param branch: The desired branch to modelize. :param force: By default, users shouldn't change the branch of a model twice. They should create a new model. """ if self._changed_branch_once and not force: raise GfbiException("You shouldn't change the branch twice.") if self.is_fake_model(): # This is the moment after we wrote the model, the model is getting # real (not fake). self._repo = Repo(self._directory) self._current_branch = branch self._changed_branch_once = True self._old_branch_name = branch.name