1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2011-2018 - TortoiseGit
4 // Copyright (C) 2006-2008, 2015 - 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.
23 #include "ProjectProperties.h"
26 * \ingroup TortoiseProc
27 * enumeration of all client hook types
42 * \ingroup TortoiseProc
43 * helper class, used as the key to the std::map we store
44 * the data for the client hook scripts in.
52 bool operator < (const hookkey
& hk
) const
54 if (htype
== hk
.htype
)
55 return (path
< hk
.path
);
57 return htype
< hk
.htype
;
62 * \ingroup TortoiseProc
63 * helper struct, used as the value to the std::map we
64 * store the data for the client hook scripts in.
66 typedef struct hookcmd
73 bool bApproved
; ///< user explicitly approved
74 bool bStored
; ///< use decision is stored in reg
78 typedef std::map
<hookkey
, hookcmd
>::iterator hookiterator
;
79 typedef std::map
<hookkey
, hookcmd
>::const_iterator const_hookiterator
;
82 * \ingroup TortoiseProc
83 * Singleton class which deals with the client hook scripts.
85 class CHooks
: public std::map
<hookkey
, hookcmd
>
91 CHooks(const CHooks
&) = delete;
92 CHooks
& operator=(const CHooks
&) = delete;
94 static void AddPathParam(CString
& sCmd
, const CTGitPathList
& pathList
);
95 static void AddCWDParam(CString
& sCmd
, const CString
& workingTree
);
96 static void AddErrorParam(CString
& sCmd
, const CString
& error
);
97 static void AddParam(CString
& sCmd
, const CString
& param
);
98 static CTGitPath
AddMessageFileParam(CString
& sCmd
, const CString
& message
);
100 /// Create the singleton. Call this at the start of the program.
101 static bool Create();
102 /// Returns the singleton instance
103 static CHooks
& Instance();
104 /// Destroys the singleton object. Call this at the end of the program.
105 static void Destroy();
108 /// Saves the hook script information to the registry.
111 * Removes the hook script identified by \c key. To make the change persistent
114 bool Remove(const hookkey
&key
);
116 * Adds a new hook script. To make the change persistent, call Save().
118 void Add(hooktype ht
, const CTGitPath
& Path
, LPCTSTR szCmd
,
119 bool bWait
, bool bShow
, bool bEnabled
, bool bLocal
);
122 * Toggles the hook script identified by \c key. Returns whether the status has changed.
123 * To make the change persistent call Save().
125 bool SetEnabled(const hookkey
& key
, bool bEnabled
);
127 /// returns the string representation of the hook type.
128 static CString
GetHookTypeString(hooktype t
);
129 /// returns the hooktype from a string representation of the same.
130 static hooktype
GetHookType(const CString
& s
);
132 /// Add hook script data from project properties
133 void SetProjectProperties(const CTGitPath
& Path
, const ProjectProperties
& pp
);
136 * Executes the Start-Commit-Hook that first matches the path in
138 * \param workingTree working tree root directory
139 * \param pathList a list of paths to look for the hook scripts
140 * \param message a commit message
141 * \param exitcode on return, contains the exit code of the hook script
142 * \param error the data the hook script outputs to stderr
143 * \remark the string "%PATHS% in the command line of the hook script is
144 * replaced with the path to a temporary file which contains a list of files
145 * in \c pathList, separated by newlines. The hook script can parse this
146 * file to get all the paths the commit is about to be done on.
147 * The string %MESSAGEFILE% is replaced with path to temporary file containing
148 * \c message. If the script finishes successfully, contents of this file
149 * is read back into \c message parameter.
151 bool StartCommit(HWND hWnd
, const CString
& workingTree
, const CTGitPathList
& pathList
, CString
& message
,
152 DWORD
& exitcode
, CString
& error
);
154 * Executes the Pre-Commit-Hook that first matches the path in
156 * \param workingTree working tree root directory
157 * \param pathList a list of paths to look for the hook scripts
158 * \param message the commit message
159 * \param exitcode on return, contains the exit code of the hook script
160 * \param error the data the hook script outputs to stderr
161 * \remark the string "%PATHS% in the command line of the hook script is
162 * replaced with the path to a temporary file which contains a list of files
163 * in \c pathList, separated by newlines. The hook script can parse this
164 * file to get all the paths the update is about to be done on.
165 * If the script finishes successfully, contents of this file is read back
166 * into \c message parameter.
168 bool PreCommit(HWND hWnd
, const CString
& workingTree
, const CTGitPathList
& pathList
,
169 CString
& message
, DWORD
& exitcode
,
172 * Executes the Post-Commit-Hook that first matches the path in
174 * \param workingTree working tree root directory
175 * \param amend commit was amend
177 bool PostCommit(HWND hWnd
, const CString
& workingTree
, bool amend
, DWORD
& exitcode
, CString
& error
);
179 bool PrePush(HWND hWnd
, const CString
& workingTree
, DWORD
& exitcode
, CString
& error
);
180 bool PostPush(HWND hWnd
, const CString
& workingTree
, DWORD
& exitcode
, CString
& error
);
182 bool PreRebase(HWND hWnd
, const CString
& workingTree
, const CString
& upstream
, const CString
& rebasedBranch
, DWORD
& exitcode
, CString
& error
);
184 bool IsHookPresent(hooktype t
, const CString
& workingTree
);
188 * Starts a new process, specified in \c cmd.
189 * \param error the data the process writes to stderr
190 * \param bWait if true, then this method waits until the created process has finished. If false, then the return
191 * value will always be 0 and \c error will be an empty string.
192 * \param bShow set to true if the process should be started visible.
193 * \return the exit code of the process if \c bWait is true, zero otherwise.
195 static DWORD
RunScript(CString cmd
, LPCTSTR currentDir
, CString
& error
, bool bWait
, bool bShow
);
197 * Find the hook script information for the hook type \c t which matches the
198 * path in \c workingTree.
200 hookiterator
FindItem(hooktype t
, const CString
& workingTree
);
202 static void ParseHookString(CString strhooks
, bool bLocal
);
205 * Checks whether the hook script has been validated already and
206 * if not, asks the user to validate it.
208 bool ApproveHook(HWND hWnd
, hookiterator it
);
210 static CHooks
* m_pInstance
;
211 static CTGitPath m_RootPath
;