git 当前日期与 GitPython 中有时之前的差异

git diff between current date and some times ago in GitPython

我正在使用 GitPython 查找一段时间内(例如现在和 1 周前)更改的文件:

 repo = Repo(self.repo_directory)
 for item in repo.head.commit.diff('develop@{1 weeks ago}'):
     print ("smth") 

但是即使将周数更改为不同的数字也没有任何反应,这意味着在该时间段内未检测到差异。如果我将 'develop@{1 weeks ago}' 更改为 'HEAD@{1 weeks ago}',那么更改的数量很大,一周内都不正确。感谢任何帮助。

develop@{1 weeks ago} 会使用 reflog

Reference logs, or "reflogs", record when the tips of branches and other references were updated in the local repository.

这意味着您的本地 Git 存储库可能没有在本地记录一周前对 develop 的任何操作,而它记录了对 "HEAD".

发生的任何操作

如果 develop 被远程更改,然后在本地导入其历史记录,develop@{1 weeks ago} 可能不会产生任何结果(因为您的本地 reflog 不会引用它)。

只有 git log --since/--until 会在 任何 日期进行操作(不仅仅是 reflog 中记录的日期,它们仅限于本地操作,默认情况下为 90 天)

但我不知道 GitPython 是否实现了它。
它的 git.refs.log 模块更多地基于 reflogs 条目,这对您的情况没有帮助。

根据评论中的讨论,我提出了以下使用 GitPython 的解决方案(此处仅放置必需的代码,忽略其余代码以避免混淆)

   import git
   from git import Repo
   from git import RemoteProgress

   class MyProgressPrinter(RemoteProgress):
       def update(op_code, cur_count, max_count=None, message=''):
          print(op_code, cur_count, max_count, cur_count / (max_count or 100.0), message or "NO MESSAGE")


   def _get_commits_info(self):
        for fetch_info in self.repo.remotes.origin.fetch(progress=MyProgressPrinter()):
        self.commits_info.append(
            (fetch_info.commit.committed_date, fetch_info.commit))  
        self.commits_info = sorted(self.commits_info, key=lambda x: x[0]) #sort based on committed date


   def _get_the_changed_components(self):
       self._get_commits_info()
       last_date = self.commits_info[-1][0]
       last_commit = self.commits_info[-1][1]
       since_date = last_date - self.time_period * 86400 # for example time_period is 7 (days)
       since_commit = self._get_since_commit(since_date) # finds the since_commit from the sorted list of commits_info 

       for item in last_commit.diff(since_commit):
           if item.a_path.find('certain_path') != -1:
               self.paths.add(item.a_path) #self.path is a set()

然而,self.path 的长度对我来说不合理,因为它捕获了太多的变化,我不确定为什么。所以基本上,我所做的是:找到所有提交,根据 committed_date 对它们进行排序,然后找到一个提交(代码中的 since_commit),其中 committed_date 用于 7 days ago.之后得到排序的 commits_info 列表中的 last commitsince_commit 之间的差异,然后将 a_pathes 保存到一个集合中。

我还尝试了另一种方法,得到了自 since_commit 从排序的 commits_info 一直到最后一次提交的每两次连续提交之间的差异。这样变化的次数就更多了。

有任何意见或帮助吗?还是您认为这是在一段时间内获得差异的正确方法?而变化次数多的原因只是偶然?

更新和最终解决方案

所以看起来比较(差异)两个提交并没有给出现在和以前有时发生的更改,因为合并之前的提交可能包括感兴趣时间段之前的更改。为此,我找到了两个解决方案,首先计算从那时到当前日期的 HEAD 更改次数,这不是很准确。为此,我们可以使用:

 g = Git(self.repo_directory)
 loginfo = g.log('--since={}'.format(since), '--pretty=tformat:') 

然后计算 Merge pull request 字符串的数量,它基本上计算了 repo 发生合并的次数,这通常会更改 HEAD。但是,它 不准确 但我们假设此计数为 31。那么:

  for item in self.repo.head.commit.diff('develop~31'):
     if item.a_path.find('certain_path') != -1:
         self.paths.add(item.a_path) #self.path is a set()

有效且简单的解决方案

  def _get_the_changed_components(self):
      g = Git(self.repo_directory)
      today = date.today()
      since = today - DT.timedelta(self.time_period) #some times ago
      loginfo = g.log('--since={}'.format(since), '--pretty=tformat:', '--name-only')
      files = loginfo.split('\n')
      for file in files:
          self.paths.add(file)