source: branches/0.7-stable/lib/SVNlog.cc @ 1108

Last change on this file since 1108 was 1108, checked in by Peter Johansson, 11 years ago

refs #458. If we lack read permission for rev, no date is retrived and
we use the date of the previous rev. This should be OK in the case
when call the log for the entire repository, but might be problematic
when calling logs of sub-nodes. Added an assertion to check that we
don't use the workaround when calling log for a sub-node.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 3.8 KB
Line 
1// $Id: SVNlog.cc 1108 2010-07-01 13:14:23Z peter $
2
3/*
4  Copyright (C) 2007, 2008 Jari Häkkinen, Peter Johansson
5  Copyright (C) 2009, 2010 Peter Johansson
6
7  This file is part of svndigest, http://dev.thep.lu.se/svndigest
8
9  svndigest is free software; you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation; either version 3 of the License, or
12  (at your option) any later version.
13
14  svndigest is distributed in the hope that it will be useful, but
15  WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  General Public License for more details.
18
19  You should have received a copy of the GNU General Public License
20  along with svndigest. If not, see <http://www.gnu.org/licenses/>.
21*/
22
23#include "SVNlog.h"
24
25#include "Commitment.h"
26#include "SVN.h"
27
28#include <algorithm>
29#include <cassert>
30#include <stdexcept>
31#include <sstream>
32#include <string>
33
34namespace theplu {
35namespace svndigest {
36
37
38  SVNlog::SVNlog(void)
39  {
40  }
41
42
43  SVNlog::SVNlog(const std::string& path)
44  {
45    SVN::instance()->client_log(path, log_message_receiver,
46                                static_cast<void*>(&lb_));
47  }
48
49
50  SVNlog::~SVNlog(void)
51  {
52  }
53
54 
55  bool SVNlog::exist(std::string name) const
56  {
57   
58    SVNlog::container::const_reverse_iterator iter = commits().rbegin();
59    for ( ; iter!= commits().rend(); ++iter)
60      if (iter->author() == name)
61        return true;
62    return false;
63  }
64
65
66  const Commitment& SVNlog::latest_commit(void) const
67  {
68    assert(commits().size());
69    return *commits().rbegin();
70  }
71
72
73  const Commitment& SVNlog::latest_commit(std::string name) const
74  {
75    SVNlog::container::const_reverse_iterator iter = commits().rbegin();
76    for ( ; iter!= commits().rend(); ++iter)
77      if (iter->author() == name)
78        return *iter;
79    std::stringstream ss;
80    ss << __FILE__ << " could not find author: " << name;
81    throw std::runtime_error(ss.str());
82    // let us return something to avoid compiler warnings
83    return *commits().begin();
84  }
85
86
87  svn_error_t* 
88  SVNlog::log_message_receiver(void *baton, apr_hash_t *changed_paths,
89                               svn_revnum_t rev, const char *author,
90                               const char *date, const char *msg,
91                               apr_pool_t *pool)
92  {
93    struct log_receiver_baton *lb=static_cast<struct log_receiver_baton*>(baton);
94    std::string d;
95    if (date && date[0])
96      d = date;
97    else if (!lb->commits.empty()) {
98      // FIXME: this is a bit hackish to fix the problem reported in
99      // ticket #458. If we lack read permission for rev, no date is
100      // retrived and we use the date of the previous rev. That should
101      // be OK if we call the super-root and previous rev truly is
102      // rev-1 (super-root contains all revs). That should be the
103      // typical case where this happens. If this would happen when
104      // calling the log of a sub-node (e.g. the trunk) this could be
105      // problematic because log is more or less sparse and when
106      // merging two sparse logs together this workaround could have
107      // strange effects such as rev+1 having a earlier date than
108      // rev. To ensure that we only allow this workaround when
109      // calling super-root, let's do the following check:
110      assert(rev == lb->commits.rbegin()->rev()+1);
111      d = lb->commits.rbegin()->date();
112    }
113    else {
114      std::stringstream msg;
115      msg << "No date defined for revision: " << rev;
116      throw SVNException(msg.str()); 
117    }
118    std::string a;
119    if (author && author[0])
120      a=author;
121    std::string message;
122    if (msg)
123      message = msg;
124    lb->commits.insert(lb->commits.end(), Commitment(a, date, message, rev));
125    return SVN_NO_ERROR;
126  }
127
128
129  void SVNlog::swap(SVNlog& rhs)
130  {
131    lb_.commits.swap(rhs.lb_.commits);
132  }
133
134
135  SVNlog& operator+=(SVNlog& lhs, const SVNlog& rhs)
136  {
137    lhs.commits().insert(rhs.commits().begin(), rhs.commits().end());
138    return lhs;
139  }
140
141}} // end of namespace svndigest and namespace theplu
Note: See TracBrowser for help on using the repository browser.