1
// TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2020, 2022-2024 - TortoiseGit
4 // Copyright (C) 2003-2008 - TortoiseSVN
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "GitRevLoglist.h"
22 #include "CommonAppUtils.h"
25 struct git_credential
;
26 struct git_indexer_progress
;
28 class ProjectProperties
;
31 * \ingroup TortoiseProc
32 * An utility class with static functions.
34 class CAppUtils
: public CCommonAppUtils
38 * Flags for StartExtDiff function.
44 bool bAlternativeTool
; // If true, invert selection of TortoiseGitMerge vs. external diff tool
46 DiffFlags(): bWait(false), bReadOnly(false), bAlternativeTool(false) {}
47 DiffFlags
& Wait(bool b
= true) { bWait
= b
; return *this; }
48 DiffFlags
& ReadOnly(bool b
= true) { bReadOnly
= b
; return *this; }
49 DiffFlags
& AlternativeTool(bool b
= true) { bAlternativeTool
= b
; return *this; }
55 #ifndef TGIT_TESTS_ONLY
57 * Launches the external merge program if there is one.
58 * \return TRUE if the program could be started
60 static BOOL
StartExtMerge(bool bAlternativeTool
,
61 const CTGitPath
& basefile
, const CTGitPath
& theirfile
, const CTGitPath
& yourfile
, const CTGitPath
& mergedfile
,
62 const CString
& basename
= CString(), const CString
& theirname
= CString(), const CString
& yourname
= CString(),
63 const CString
& mergedname
= CString(), bool bReadOnly
= false, HWND resolveMsgHwnd
= nullptr, bool bDeleteBaseTheirsMineOnClose
= false);
66 * Starts the external patch program (currently always TortoiseGitMerge)
68 static BOOL
StartExtPatch(const CTGitPath
& patchfile
, const CTGitPath
& dir
,
69 const CString
& sOriginalDescription
= CString(), const CString
& sPatchedDescription
= CString(),
70 BOOL bReversed
= FALSE
, BOOL bWait
= FALSE
);
73 * Starts the external unified diff viewer (the app associated with *.diff or *.patch files).
74 * If no app is associated with those file types, the default text editor is used.
76 static BOOL
StartUnifiedDiffViewer(const CString
& patchfile
, const CString
& title
, BOOL bWait
= FALSE
, bool bAlternativeTool
= false);
79 * Sets up all the default diff and merge scripts.
80 * \param force if true, overwrite all existing entries
81 * \param either "Diff", "Merge" or an empty string
83 static bool SetupDiffScripts(bool force
, const CString
& type
);
86 * Starts the external diff application
88 static bool StartExtDiff(
89 const CString
& file1
, const CString
& file2
,
90 const CString
& sName1
, const CString
& sName2
,
91 const CString
& originalFile1
, const CString
& originalFile2
,
92 const CGitHash
& hash1
, const CGitHash
& hash2
, const DiffFlags
& flags
, int jumpToLine
= 0);
95 * Launches the standard text viewer/editor application which is associated
97 * \return TRUE if the program could be started.
99 static BOOL
StartTextViewer(CString file
);
102 * Launch the external blame viewer
104 static bool LaunchTortoiseBlame(
105 const CString
& sBlameFile
, const CString
& Rev
, const CString
& sParams
= CString());
108 * Launch alternative editor
110 static bool LaunchAlternativeEditor(const CString
& filename
, bool uac
= false);
114 static CString
FormatWindowTitle(const CString
& urlorpath
, const CString
& dialogname
, const CString
& appname
, DWORD format
);
117 #ifndef TGIT_TESTS_ONLY
119 * Sets the title of a dialog
121 static void SetWindowTitle(const CWnd
& dialog
, const CString
& urlorpath
);
122 static void SetWindowTitle(HWND hWnd
, const CString
& urlorpath
, const CString
& dialogname
);
125 * Formats text in a rich edit control (version 2).
126 * text in between * chars is formatted bold
127 * text in between ^ chars is formatted italic
128 * text in between _ chars is underlined
130 static bool FormatTextInRichEditControl(CWnd
* pWnd
);
132 static bool FindStyleChars(const CString
& sText
, wchar_t stylechar
, int& start
, int& end
);
133 static bool FindWarningsErrors(const CString
& text
, std::vector
<CHARRANGE
>& rangeErrors
, std::vector
<CHARRANGE
>& rangeWarnings
);
134 #ifndef TGIT_TESTS_ONLY
136 * highlight warnings and errors returned by git command in rich edit control colored in bold
138 static BOOL
StyleWarningsErrors(const CString
& text
, CRichEditCtrl
* edit
);
140 * implements URL searching with the same logic as CSciEdit::StyleURLs
143 static std::vector
<CHARRANGE
> FindURLMatches(const CString
& msg
);
144 #ifndef TGIT_TESTS_ONLY
145 static BOOL
StyleURLs(const CString
& msg
, CWnd
* pWnd
);
148 * Replacement for GitDiff::ShowUnifiedDiff(), but started as a separate process.
150 static bool StartShowUnifiedDiff(HWND hWnd
, const CTGitPath
& url1
, const CString
& rev1
,
151 const CTGitPath
& url2
, const CString
& rev2
,
153 //const GitRev& peg = GitRev(), const GitRev& headpeg = GitRev(),
154 bool bAlternateDiff
= false,
155 bool bIgnoreAncestry
= false,
158 bool bCompact
= false,
159 bool bNoPrefix
= false);
161 static bool Export(HWND hWnd
, const CString
* BashHash
= nullptr, const CTGitPath
* orgPath
= nullptr);
162 static bool UpdateBranchDescription(const CString
& branch
, CString description
);
163 static bool CreateBranchTag(HWND hWnd
, bool isTag
= true, const CString
* ref
= nullptr, bool switchNewBranch
= false, LPCWSTR name
= nullptr);
164 static bool CreateWorktree(HWND hWnd
, const CString
& target
= CString());
165 static bool Switch(HWND hWnd
, const CString
& initialRefName
= CString());
166 static bool PerformSwitch(HWND hWnd
, const CString
& ref
, bool bForce
= false, const CString
& sNewBranch
= CString(), bool bBranchOverride
= false, BOOL bTrack
= 2, bool bMerge
= false);
168 static bool IgnoreFile(HWND hWnd
, const CTGitPathList
& filelist
, bool IsMask
);
169 static bool GitReset(HWND hWnd
, const CString
& ref
, int type
= 1);
170 static bool ConflictEdit(HWND hWnd
, CTGitPath
& file
, bool bAlternativeTool
= false, bool revertTheirMy
= false, HWND resolveMsgHwnd
= nullptr);
171 static void GetConflictTitles(CString
* baseText
, CString
& mineText
, CGitHash
* mineHash
, CString
& theirsText
, CGitHash
* theirsHash
, bool rebaseActive
);
173 static CString
GetMergeTempFile(const CString
& str
, const CTGitPath
& merge
, bool returnAbsolutePath
= true);
174 static bool StashSave(HWND hWnd
, const CString
& msg
= CString(), bool showPull
= false, bool pullShowPush
= false, bool showMerge
= false, const CString
& mergeRev
= CString());
175 static bool StashApply(HWND hWnd
, CString ref
, bool showChanges
= true);
176 /** Execute "stash pop"
178 * 0: only show info on error (and allow to diff on error)
179 * 1: allow to open diff dialog on error or success
180 * 2: only show error or success message
182 static bool StashPop(HWND hWnd
, int showChanges
= 1);
184 static bool IsSSHPutty();
186 static bool LaunchRemoteSetting();
188 static bool LaunchPAgent(HWND hWnd
, const CString
* keyfile
= nullptr, const CString
* pRemote
= nullptr);
190 static bool ShellOpen(const CString
& file
, HWND hwnd
= nullptr);
191 static bool ShowOpenWithDialog(const CString
& file
, HWND hwnd
= nullptr);
193 static CString
GetClipboardLink(const CString
& skipGitPrefix
= L
"", int paramsCount
= 0);
194 static CString
ChooseRepository(HWND hWnd
, const CString
* path
);
196 static bool SendPatchMail(HWND hWnd
, CTGitPathList
& pathlist
);
197 static bool SendPatchMail(HWND hWnd
, const CString
& cmd
, const CString
& formatpatchoutput
);
199 static int SaveCommitUnicodeFile(const CString
& filename
, CString
& mesage
);
200 static bool MessageContainsConflictHints(HWND hWnd
, const CString
& message
);
202 static int GetLogOutputEncode(CGit
*pGit
=&g_Git
);
204 static bool Pull(HWND hWnd
, bool showPush
= false, bool showStashPop
= false);
205 // rebase = 1: ask user what to do, rebase = 2: run autorebase
206 static bool RebaseAfterFetch(HWND hWnd
, const CString
& upstream
= L
"", int rebase
= 0, bool preserveMerges
= false);
207 static bool Fetch(HWND hWnd
, const CString
& remoteName
= L
"", bool allRemotes
= false);
208 static bool DoPush(HWND hWnd
, bool autoloadKey
, bool tags
, bool allRemotes
, bool allBranches
, bool force
, bool forceWithLease
, const CString
& localBranch
, const CString
& remote
, const CString
& remoteBranch
, bool setUpstream
, int recurseSubmodules
, const CString
& pushOption
);
209 static bool Push(HWND hWnd
, const CString
& selectLocalBranch
= CString(), int pushAll
= BST_INDETERMINATE
);
210 static bool RequestPull(HWND hWnd
, const CString
& endrevision
= L
"", const CString
& repositoryUrl
= L
"");
212 static void RemoveTrailSlash(CString
&path
);
214 static bool CheckUserData(HWND hWnd
);
216 static BOOL
Commit(HWND hWnd
, const CString
& bugid
, BOOL bWholeProject
, CString
& sLogMsg
,
217 CTGitPathList
&pathList
,
218 bool bSelectFilesForCommit
);
220 static BOOL
SVNDCommit(HWND hWnd
);
221 static BOOL
Merge(HWND hWnd
, const CString
* commit
= nullptr, bool showStashPop
= false);
222 static BOOL
MergeAbort(HWND hWnd
);
223 static void RemoveTempMergeFile(const CTGitPath
& path
, bool pathIsRelative
= true);
224 static void EditNote(HWND hWnd
, GitRevLoglist
* rev
, ProjectProperties
* projectProperties
);
225 static int GetMsysgitVersion(HWND hWnd
);
226 static bool IsGitVersionNewerOrEqual(HWND hWnd
, unsigned __int8 major
, unsigned __int8 minor
, unsigned __int8 patchlevel
= 0, unsigned __int8 build
= 0);
227 static void MarkWindowAsUnpinnable(HWND hWnd
);
229 static bool BisectStart(HWND hWnd
, const CString
& lastGood
, const CString
& firstBad
);
230 static bool BisectOperation(HWND hWnd
, const CString
& op
, const CString
& ref
= L
"");
232 static int Git2GetUserPassword(git_credential
** out
, const char* url
, const char* username_from_url
, unsigned int allowed_types
, void* payload
);
234 static int Git2CertificateCheck(git_cert
*cert
, int valid
, const char* host
, void *payload
);
236 static int ExploreTo(HWND hwnd
, CString path
);
238 static bool DeleteRef(CWnd
* parent
, const CString
& ref
);
240 static void SetupBareRepoIcon(const CString
& path
);
242 static bool IsTGitRebaseActive(HWND hWnd
);
245 static CString
PickDiffTool(const CTGitPath
& file1
, const CTGitPath
& file2
);
247 static bool OpenIgnoreFile(HWND hWnd
, CIgnoreFile
& file
, const CString
& filename
);
249 static void DescribeConflictFile(bool mode
, bool base
,CString
&descript
);