KiCad PCB EDA Suite
Loading...
Searching...
No Matches
project_git_utils.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.TXT for contributors.
5 *
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 3
9 * of the License, or (at your option) any later version.
10 *
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.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/gpl-3.0.html
19 * or you may search the http://www.gnu.org website for the version 3 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include "project_git_utils.h"
25#include "git_backend.h"
26
27#include <wx/filename.h>
28#include <wx/string.h>
29#include <string_utils.h>
30
31#ifndef __WINDOWS__
32#include <climits>
33#include <cstdlib>
34#endif
35
36namespace KIGIT
37{
38
39git_repository* PROJECT_GIT_UTILS::GetRepositoryForFile( const char* aFilename )
40{
41 return GetGitBackend()->GetRepositoryForFile( aFilename );
42}
43
44
45int PROJECT_GIT_UTILS::CreateBranch( git_repository* aRepo, const wxString& aBranchName )
46{
47 return GetGitBackend()->CreateBranch( aRepo, aBranchName );
48}
49
50
51bool PROJECT_GIT_UTILS::RemoveVCS( git_repository*& aRepo, const wxString& aProjectPath,
52 bool aRemoveGitDir, wxString* aErrors )
53{
54 return GetGitBackend()->RemoveVCS( aRepo, aProjectPath, aRemoveGitDir, aErrors );
55}
56
57
58wxString PROJECT_GIT_UTILS::GetCurrentHash( const wxString& aProjectFile, bool aShort )
59{
60 wxString result = wxT( "no hash" );
61 git_repository* repo = PROJECT_GIT_UTILS::GetRepositoryForFile( TO_UTF8( aProjectFile ) );
62
63 if( repo )
64 {
65 git_reference* head = nullptr;
66
67 if( git_repository_head( &head, repo ) == 0 )
68 {
69 const git_oid* oid = git_reference_target( head );
70
71 if( oid )
72 {
73 char buf[GIT_OID_HEXSZ + 1];
74 size_t len = aShort ? 9 : GIT_OID_HEXSZ + 1; // 8 chars + null terminator
75 git_oid_tostr( buf, len, oid );
76 result = wxString::FromUTF8( buf );
77 }
78
79 git_reference_free( head );
80 }
81
82 git_repository_free( repo );
83 }
84
85 return result;
86}
87
88
89wxString PROJECT_GIT_UTILS::ComputeSymlinkPreservingWorkDir( const wxString& aUserProjectPath,
90 const wxString& aCanonicalWorkDir )
91{
92#ifdef __WINDOWS__
93 return aCanonicalWorkDir;
94#else
95 if( aUserProjectPath.IsEmpty() || aCanonicalWorkDir.IsEmpty() )
96 return aCanonicalWorkDir;
97
98 char resolvedPath[PATH_MAX];
99
100 if( realpath( aUserProjectPath.mb_str(), resolvedPath ) == nullptr )
101 return aCanonicalWorkDir;
102
103 wxString canonicalUserPath = wxString::FromUTF8( resolvedPath );
104
105 if( !canonicalUserPath.EndsWith( wxFileName::GetPathSeparator() ) )
106 canonicalUserPath += wxFileName::GetPathSeparator();
107
108 wxString canonicalWorkDirNorm = aCanonicalWorkDir;
109
110 if( !canonicalWorkDirNorm.EndsWith( wxFileName::GetPathSeparator() ) )
111 canonicalWorkDirNorm += wxFileName::GetPathSeparator();
112
113 // The workdir could be at or above the project directory
114 if( canonicalUserPath.StartsWith( canonicalWorkDirNorm ) )
115 {
116 return aUserProjectPath.EndsWith( wxFileName::GetPathSeparator() )
117 ? aUserProjectPath
118 : aUserProjectPath + wxFileName::GetPathSeparator();
119 }
120
121 // The workdir is above the user path - find the portion that corresponds to the workdir
122 wxFileName userFn( aUserProjectPath );
123 wxFileName workDirFn( aCanonicalWorkDir );
124 wxArrayString workDirParts = workDirFn.GetDirs();
125 size_t workDirDepth = workDirParts.GetCount();
126
127 wxFileName canonicalUserFn( canonicalUserPath );
128 wxArrayString canonicalUserParts = canonicalUserFn.GetDirs();
129
130 if( canonicalUserParts.GetCount() < workDirDepth )
131 return aCanonicalWorkDir;
132
133 wxArrayString canonicalWorkDirParts = workDirFn.GetDirs();
134
135 for( size_t i = 0; i < workDirDepth; ++i )
136 {
137 if( canonicalUserParts[i] != canonicalWorkDirParts[i] )
138 return aCanonicalWorkDir;
139 }
140
141 wxArrayString userParts = userFn.GetDirs();
142
143 if( userParts.GetCount() < workDirDepth )
144 return aCanonicalWorkDir;
145
146 wxString result = userFn.GetVolume();
147
148 if( !result.IsEmpty() )
149 result += wxFileName::GetVolumeSeparator();
150
151 result += wxFileName::GetPathSeparator();
152
153 for( size_t i = 0; i < workDirDepth; ++i )
154 {
155 result += userParts[i];
156 result += wxFileName::GetPathSeparator();
157 }
158
159 return result;
160#endif
161}
162
163} // namespace KIGIT
virtual int CreateBranch(git_repository *aRepo, const wxString &aBranchName)=0
virtual bool RemoveVCS(git_repository *&aRepo, const wxString &aProjectPath, bool aRemoveGitDir, wxString *aErrors)=0
virtual git_repository * GetRepositoryForFile(const char *aFilename)=0
static wxString GetCurrentHash(const wxString &aProjectFile, bool aShort)
Return the current HEAD commit hash for the repository containing aProjectFile.
static git_repository * GetRepositoryForFile(const char *aFilename)
Discover and open the repository that contains the given file.
static wxString ComputeSymlinkPreservingWorkDir(const wxString &aUserProjectPath, const wxString &aCanonicalWorkDir)
Compute a working directory path that preserves symlinks from the user's project path.
static bool RemoveVCS(git_repository *&aRepo, const wxString &aProjectPath=wxEmptyString, bool aRemoveGitDir=false, wxString *aErrors=nullptr)
Remove version control from a directory by freeing the repository and optionally removing the ....
static int CreateBranch(git_repository *aRepo, const wxString &aBranchName)
Create a new branch based on HEAD.
GIT_BACKEND * GetGitBackend()
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
wxString result
Test unit parsing edge cases and error handling.