1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25 
26 #include "gitsettings.h"
27 
28 #include <utils/environment.h>
29 #include <utils/layoutbuilder.h>
30 
31 #include <vcsbase/vcsbaseconstants.h>
32 
33 #include <QDir>
34 
35 using namespace Utils;
36 using namespace VcsBase;
37 
38 namespace Git {
39 namespace Internal {
40 
GitSettings()41 GitSettings::GitSettings()
42 {
43     setSettingsGroup("Git");
44 
45     path.setDisplayStyle(StringAspect::LineEditDisplay);
46     path.setLabelText(tr("Prepend to PATH:"));
47 
48     registerAspect(&binaryPath);
49     binaryPath.setDefaultValue("git");
50 
51     registerAspect(&pullRebase);
52     pullRebase.setSettingsKey("PullRebase");
53     pullRebase.setLabelText(tr("Pull with rebase"));
54 
55     registerAspect(&showTags);
56     showTags.setSettingsKey("ShowTags");
57 
58     registerAspect(&omitAnnotationDate);
59     omitAnnotationDate.setSettingsKey("OmitAnnotationDate");
60 
61     registerAspect(&ignoreSpaceChangesInDiff);
62     ignoreSpaceChangesInDiff.setSettingsKey("SpaceIgnorantDiff");
63     ignoreSpaceChangesInDiff.setDefaultValue(true);
64 
65     registerAspect(&ignoreSpaceChangesInBlame);
66     ignoreSpaceChangesInBlame.setSettingsKey("SpaceIgnorantBlame");
67     ignoreSpaceChangesInBlame.setDefaultValue(true);
68 
69     registerAspect(&blameMoveDetection);
70     blameMoveDetection.setSettingsKey("BlameDetectMove");
71     blameMoveDetection.setDefaultValue(0);
72 
73     registerAspect(&diffPatience);
74     diffPatience.setSettingsKey("DiffPatience");
75     diffPatience.setDefaultValue(true);
76 
77     registerAspect(&winSetHomeEnvironment);
78     winSetHomeEnvironment.setSettingsKey("WinSetHomeEnvironment");
79     winSetHomeEnvironment.setDefaultValue(true);
80     winSetHomeEnvironment.setLabelText(tr("Set \"HOME\" environment variable"));
81     if (HostOsInfo::isWindowsHost()) {
82         const QByteArray currentHome = qgetenv("HOME");
83         const QString toolTip
84                 = tr("Set the environment variable HOME to \"%1\"\n(%2).\n"
85                      "This causes Git to look for the SSH-keys in that location\n"
86                      "instead of its installation directory when run outside git bash.").
87                 arg(QDir::homePath(),
88                     currentHome.isEmpty() ? tr("not currently set") :
89                             tr("currently set to \"%1\"").arg(QString::fromLocal8Bit(currentHome)));
90         winSetHomeEnvironment.setToolTip(toolTip);
91     } else {
92         winSetHomeEnvironment.setVisible(false);
93     }
94 
95     registerAspect(&gitkOptions);
96     gitkOptions.setDisplayStyle(StringAspect::LineEditDisplay);
97     gitkOptions.setSettingsKey("GitKOptions");
98     gitkOptions.setLabelText(tr("Arguments:"));
99 
100     registerAspect(&logDiff);
101     logDiff.setSettingsKey("LogDiff");
102     logDiff.setToolTip(tr("Note that huge amount of commits might take some time."));
103 
104     registerAspect(&repositoryBrowserCmd);
105     repositoryBrowserCmd.setDisplayStyle(StringAspect::PathChooserDisplay);
106     repositoryBrowserCmd.setSettingsKey("RepositoryBrowserCmd");
107     repositoryBrowserCmd.setExpectedKind(PathChooser::ExistingCommand);
108     repositoryBrowserCmd.setHistoryCompleter("Git.RepoCommand.History");
109     repositoryBrowserCmd.setDisplayName(tr("Git Repository Browser Command"));
110     repositoryBrowserCmd.setLabelText(tr("Command:"));
111 
112     registerAspect(&graphLog);
113     graphLog.setSettingsKey("GraphLog");
114 
115     registerAspect(&colorLog);
116     colorLog.setSettingsKey("ColorLog");
117     colorLog.setDefaultValue(true);
118 
119     registerAspect(&firstParent);
120     firstParent.setSettingsKey("FirstParent");
121 
122     registerAspect(&followRenames);
123     followRenames.setSettingsKey("FollowRenames");
124     followRenames.setDefaultValue(true);
125 
126     registerAspect(&lastResetIndex);
127     lastResetIndex.setSettingsKey("LastResetIndex");
128 
129     registerAspect(&refLogShowDate);
130     refLogShowDate.setSettingsKey("RefLogShowDate");
131 
132     timeout.setDefaultValue(Utils::HostOsInfo::isWindowsHost() ? 60 : 30);
133 }
134 
gitExecutable(bool * ok,QString * errorMessage) const135 FilePath GitSettings::gitExecutable(bool *ok, QString *errorMessage) const
136 {
137     // Locate binary in path if one is specified, otherwise default to pathless binary.
138     if (ok)
139         *ok = true;
140     if (errorMessage)
141         errorMessage->clear();
142 
143     FilePath binPath = binaryPath.filePath();
144     if (!binPath.isAbsolutePath()) {
145         Environment env = Environment::systemEnvironment();
146         if (!path.filePath().isEmpty())
147             env.prependOrSetPath(path.filePath().toString());
148         binPath = env.searchInPath(binPath.toString());
149     }
150     if (binPath.isEmpty()) {
151         if (ok)
152             *ok = false;
153         if (errorMessage)
154             *errorMessage = tr("The binary \"%1\" could not be located in the path \"%2\"")
155                 .arg(binaryPath.value(), path.value());
156     }
157     return binPath;
158 }
159 
160 // GitSettingsPage
161 
GitSettingsPage(GitSettings * settings)162 GitSettingsPage::GitSettingsPage(GitSettings *settings)
163 {
164     setId(VcsBase::Constants::VCS_ID_GIT);
165     setDisplayName(GitSettings::tr("Git"));
166     setCategory(VcsBase::Constants::VCS_SETTINGS_CATEGORY);
167     setSettings(settings);
168 
169     setLayouter([settings](QWidget *widget) {
170         GitSettings &s = *settings;
171         using namespace Layouting;
172 
173         Column {
174             Group {
175                 Title(GitSettings::tr("Configuration")),
176                 Row { s.path },
177                 s.winSetHomeEnvironment,
178             },
179 
180             Group {
181                 Title(GitSettings::tr("Miscellaneous")),
182                 Row { s.logCount, s.timeout, Stretch() },
183                 s.pullRebase
184             },
185 
186             Group {
187                 Title(GitSettings::tr("Gitk")),
188                 Row { s.gitkOptions }
189             },
190 
191             Group {
192                 Title(GitSettings::tr("Repository Browser")),
193                 Row { s.repositoryBrowserCmd }
194             },
195 
196             Stretch()
197         }.attachTo(widget);
198     });
199 }
200 
201 } // namespace Internal
202 } // namespace Git
203