#!python3
# Copyright 2007-2017 Gemr. All Rights Reserved.
# Licensed to MIT see LICENSE.txt
import os
import warnings
from time import sleep
import gdeps as GDeps
__author__ = 'Suryavarman (http://sourceforge.net/u/suryavarman/profile/)'
[docs]class Git(GDeps.Versioning):
def __init__(self, inConfigFile, inFolderPath, inLogFileDirectory, inReposUrl, inCloneArgs="", inUpdateArgs="", inSectionName="git", inExePath="C:\\Program Files (x86)\\Git\\bin\\git.exe"):
""" use the inCloneArgs to setup the branch name
@bug if you have a SSL certificate problem: self signed certificate
in certificate chain :
1) Try to use the read only link :
sourceforge : use -> git://git.code.sf.net/p/REPONAME/code
bitbucket : use -> https://bitbucket.org/REPOSOWNERNAME/REPONAME.git
github : use -> https://github.com/REPOSOWNERNAME/REPONAME.git
2)
- Create an account on the platform (like github/bitbucket/sourceforge
- create an asynchrone key
- use a service like pageant/keypass-pageant to
automatically load the key
@bug TGitCache.exe
X:\BLABLA\.git\objects\pack\pack-2607c216fea942cbbaf550dfc5156383de838b10.idx - Access is denied.
X:\BLABLA\.git\objects\pack\pack-2607c216fea942cbbaf550dfc5156383de838b10.pack - The process cannot access the file because it is being used by another process.
Disable ToirtoiseGit cache :
> Open TortoiseGit Settings
CmD example : "C:\Program Files\TortoiseGit\bin\TortoiseGitProc.exe" /command:settings
> Icon Overlays
> In section "Status cache" select "None"
> Click OK
TGitCache.exe will disappear from the process list.
@link https://stackoverflow.com/questions/16773257/how-can-i-stop-and-start-tgitcache-exe-gracefully
or every time you have to delete manually the .git or all the directory or reboot your pc.
"""
GDeps.Versioning.__init__(self, inConfigFile, inFolderPath, inLogFileDirectory, inReposUrl, inCloneArgs, inUpdateArgs, inSectionName, inExePath)
self.m_ErrorRegexp = r"(fatal:.*|error:.*)" # .*git:.*
self.m_CMDSetSSL = "-c http.sslVerify=false "
""" SSL certificate problem: self signed certificate in certificate chain
@link https://stackoverflow.com/questions/11621768/how-can-i-make-git-accept-a-self-signed-certificate
"""
[docs] def clone(self):
"""
How to clone a branch:
gdeps.Keys.ms_RepoCloneArgs: "--branch boost-1.64.0"
The logs files will be:
self.m_LogFileDirectory + "\\git-clone.log"
and also if there are Clone Args :
self.m_LogFileDirectory + "\\git-checkout.log"
usage: git clone [<options>] [--] <repo> [<dir>]
-v, --verbose be more verbose
-q, --quiet be more quiet
--progress force progress reporting
-n, --no-checkout don't create a checkout
--bare create a bare repository
--mirror create a mirror repository (implies bare)
-l, --local to clone from a local repository
--no-hardlinks don't use local hardlinks, always copy
-s, --shared setup as shared repository
--recursive initialize submodules in the clone
--recurse-submodules initialize submodules in the clone
--template <template-directory>
directory from which templates will be used
--reference <repo> reference repository
--dissociate use --reference only while cloning
-o, --origin <name> use <name> instead of 'origin' to track upstream
-b, --branch <branch>
checkout <branch> instead of the remote's HEAD
-u, --upload-pack <path>
path to git-upload-pack on the remote
--depth <depth> create a shallow clone of that depth
--single-branch clone only one branch, HEAD or --branch
--separate-git-dir <gitdir>
separate git dir from working tree
-c, --config <key=value>
set config inside the new repository
"""
if 'git@' in self.m_ReposUrl:
warnings.warn("Try to use a repo url with https and not a ssh url: self.m_ReposUrl or"
" read that : http://stackoverflow.com/questions/13363553/git-error-host-key-verification-failed-when-connecting-to-remote-repository")
aReport = GDeps.Versioning.clone(self)
aCommand = self.getCMDExePath()
aGitCommand = self.m_CMDSetSSL + "clone "
if '--branch' in self.m_CloneArgs:
aGitCommand += self.m_CloneArgs + " "
aGitCommand += "--recursive "
aCommand += aGitCommand + '"' + self.m_ReposUrl + '" "' + self.getCloneTmpDir() + '"'
self.CloneNoEmptyDir(aCommand, "git-clone", aReport)
if self.m_CloneArgs and '--branch' not in self.m_CloneArgs:
aCurrentDir = os.getcwd()
os.chdir(self.m_FolderPath)
# if '--branch' in self.m_CloneArgs:
# # http://stackoverflow.com/questions/20280726/how-to-git-clone-a-specific-tag
# aCheckoutCommand = self.getCMDExePath() + "clone " + self.m_CloneArgs + " " + self.m_ReposUrl
# #aCheckoutCommand = self.getCMDExePath() + self.m_CMDSetSSL + "checkout --track "# + self.m_CloneArgs
# self.callWithLogFile(aCheckoutCommand, "git-clone-branch", aReport, self)
#
# # example : git.exe clone --progress --branch test_branch -v "git@github.com:Suryavarman/gdeps-ut-test-git.git" "X:\test_git\gdeps-ut-test-git"
# else:
# https://stackoverflow.com/questions/791959/download-a-specific-tag-with-git
# https://git-scm.com/docs/git-checkout
# https://git-scm.com/book/fr/v1/Les-branches-avec-Git-Les-branches-distantes
# GDeps.call( self.m_ExePath + " fetch" )
# GDeps.call( self.m_ExePath + " checkout " + self.m_Args )
# aCheckoutCommand = self.getCMDExePath() + self.m_CMDSetSSL + "checkout -b " + self.m_CloneArgs
#
# self.callWithLogFile(aCheckoutCommand, "git-checkout", aReport, self)
aCheckoutCommand = self.getCMDExePath() + self.m_CMDSetSSL + "checkout --track " + self.m_CloneArgs
self.callWithLogFile(aCheckoutCommand, "git-checkout", aReport, self, inAppend=True)
# There are a delay, we have to wait the end folder creation (copy/past).
aTimeRemind = 60.0 # 60 seconds
aGitFolderName = os.path.normpath(self.m_FolderPath + r'\\' + self.getFolderRepoConfigPath())
while aTimeRemind > 0 and not os.path.exists(aGitFolderName):
sleep(1.0) # wait one seconds
aTimeRemind -= 1.0
assert aTimeRemind >= 0, "The " + aGitFolderName + " folder doesn't exist."
os.chdir(aCurrentDir)
self.subModuleUpdate(aReport)
return aReport
[docs] def update(self):
""" The log file will be self.m_LogFileDirectory + "\\git-update.log"
"""
aReport = GDeps.Versioning.update(self)
aCommand = self.getCMDExePath()
aCurrentDir = os.getcwd()
os.chdir(self.m_FolderPath)
aCommand += self.m_CMDSetSSL + "pull" + (" " + self.m_UpdateArgs if self.m_UpdateArgs else "")
self.callWithLogFile(aCommand, "git-update", aReport, self)
os.chdir(aCurrentDir)
self.subModuleUpdate(aReport)
return aReport
[docs] def clean(self):
""" The log file will be self.m_LogFileDirectory + "\\git-clean.log"
"""
aReport = GDeps.Versioning.clean(self)
aCommand = self.getCMDExePath()
aCurrentDir = os.getcwd()
os.chdir(self.m_FolderPath)
aCommand += self.m_CMDSetSSL + "reset --hard"
self.callWithLogFile(aCommand, "git-clean", aReport, self)
os.chdir(aCurrentDir)
return aReport
[docs] def getFolderRepoConfigPath(self):
return ".git"
[docs] def subModuleUpdate(self, inReport):
""" Has to be call after a clone and an update. """
aCommand = self.getCMDExePath()
aCurrentDir = os.getcwd()
os.chdir(self.m_FolderPath)
aCommand += self.m_CMDSetSSL + "submodule update --recursive"
self.callWithLogFile(aCommand, "git-m", inReport, self)
os.chdir(aCurrentDir)