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
44int PROJECT_GIT_UTILS::CreateBranch( git_repository* aRepo, const wxString& aBranchName )
45{
46 return GetGitBackend()->CreateBranch( aRepo, aBranchName );
47}
48
49bool PROJECT_GIT_UTILS::RemoveVCS( git_repository*& aRepo, const wxString& aProjectPath,
50 bool aRemoveGitDir, wxString* aErrors )
51{
52 return GetGitBackend()->RemoveVCS( aRepo, aProjectPath, aRemoveGitDir, aErrors );
53}
54
55wxString PROJECT_GIT_UTILS::GetCurrentHash( const wxString& aProjectFile, bool aShort )
56{
57 wxString result = wxT( "no hash" );
58 git_repository* repo = PROJECT_GIT_UTILS::GetRepositoryForFile( TO_UTF8( aProjectFile ) );
59
60 if( repo )
61 {
62 git_reference* head = nullptr;
63
64 if( git_repository_head( &head, repo ) == 0 )
65 {
66 const git_oid* oid = git_reference_target( head );
67
68 if( oid )
69 {
70 char buf[GIT_OID_HEXSZ + 1];
71 size_t len = aShort ? 9 : GIT_OID_HEXSZ + 1; // 8 chars + null terminator
72 git_oid_tostr( buf, len, oid );
73 result = wxString::FromUTF8( buf );
74 }
75
76 git_reference_free( head );
77 }
78
79 git_repository_free( repo );
80 }
81
82 return result;
83}
84
85
86wxString PROJECT_GIT_UTILS::ComputeSymlinkPreservingWorkDir( const wxString& aUserProjectPath,
87 const wxString& aCanonicalWorkDir )
88{
89#ifdef __WINDOWS__
90 return aCanonicalWorkDir;
91#else
92 if( aUserProjectPath.IsEmpty() || aCanonicalWorkDir.IsEmpty() )
93 return aCanonicalWorkDir;
94
95 char resolvedPath[PATH_MAX];
96
97 if( realpath( aUserProjectPath.mb_str(), resolvedPath ) == nullptr )
98 return aCanonicalWorkDir;
99
100 wxString canonicalUserPath = wxString::FromUTF8( resolvedPath );
101
102 if( !canonicalUserPath.EndsWith( wxFileName::GetPathSeparator() ) )
103 canonicalUserPath += wxFileName::GetPathSeparator();
104
105 wxString canonicalWorkDirNorm = aCanonicalWorkDir;
106
107 if( !canonicalWorkDirNorm.EndsWith( wxFileName::GetPathSeparator() ) )
108 canonicalWorkDirNorm += wxFileName::GetPathSeparator();
109
110 // The workdir could be at or above the project directory
111 if( canonicalUserPath.StartsWith( canonicalWorkDirNorm ) )
112 {
113 return aUserProjectPath.EndsWith( wxFileName::GetPathSeparator() )
114 ? aUserProjectPath
115 : aUserProjectPath + wxFileName::GetPathSeparator();
116 }
117
118 // The workdir is above the user path - find the portion that corresponds to the workdir
119 wxFileName userFn( aUserProjectPath );
120 wxFileName workDirFn( aCanonicalWorkDir );
121 wxArrayString workDirParts = workDirFn.GetDirs();
122 size_t workDirDepth = workDirParts.GetCount();
123
124 wxFileName canonicalUserFn( canonicalUserPath );
125 wxArrayString canonicalUserParts = canonicalUserFn.GetDirs();
126
127 if( canonicalUserParts.GetCount() < workDirDepth )
128 return aCanonicalWorkDir;
129
130 wxArrayString canonicalWorkDirParts = workDirFn.GetDirs();
131
132 for( size_t i = 0; i < workDirDepth; ++i )
133 {
134 if( canonicalUserParts[i] != canonicalWorkDirParts[i] )
135 return aCanonicalWorkDir;
136 }
137
138 wxArrayString userParts = userFn.GetDirs();
139
140 if( userParts.GetCount() < workDirDepth )
141 return aCanonicalWorkDir;
142
143 wxString result = userFn.GetVolume();
144
145 if( !result.IsEmpty() )
146 result += wxFileName::GetVolumeSeparator();
147
148 result += wxFileName::GetPathSeparator();
149
150 for( size_t i = 0; i < workDirDepth; ++i )
151 {
152 result += userParts[i];
153 result += wxFileName::GetPathSeparator();
154 }
155
156 return result;
157#endif
158}
159
160} // 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.