czproject / git-php Goto Github PK
View Code? Open in Web Editor NEWLibrary for work with Git repositories in PHP.
License: Other
Library for work with Git repositories in PHP.
License: Other
Hi ,
I need clone repository from http on client PC , have a sample Code with git-php
. Client send a request for clone and php script response it.
like a
'git clone http://web/myscript/repo.git'
'git pull and push ...'
The method "addFile" seems to remove any URL-encoded umlauts (e.g. äöü) in the filename...?
Here is a snippet of the code that works just fine with any filename that has no umlaut in it:
# the variable $gitfilename contains the string "/tmp/Test,Test G\xc3\xbcnther__test.txt" wich is the encoded form of "/tmp/Test,Test Günther__test.txt"
$val = file_put_contents($gitfilename, $txt, FILE_APPEND);
echo('Successfully written ' . $val . ' bytes to file ' . $gitfilename);
# Output: Successfully written 534 bytes to file /tmp/Test,Test G\xc3\xbcnther__test.txt
# Note that the file is now correctly listed in the file system:
# ls -al
# -rw-rw---- 1 user group 534 Jan 29 09:09 'Test,Test Günther__test.txt'
$repo->addFile($gitfilename);
# git exception: Command 'git add --end-of-options '/tmp/Test,Test Gnther__test.txt'' failed (exit-code 128)
Hello!
I've been trying to use your library to push to a new repository created via GitHub API on my app.
I've been able to make everything work so far, but I am having trouble with the git remote add
and git push
bits of my flow.
Imagine I wanted to do exactly as GitHub suggests when setting a new remote and pushing to it:
git remote add origin [email protected]:organization/repository.git
and then
git push -u origin master
How would I achieve this?
Here's what I've been trying:
$new_repository->addRemote('origin', '[email protected]:organization/repository.git');
$new_repository->push('origin', ['--set-upstream']);
But this keeps failing with this being logged:
Cz\Git\GitException: Command 'git push origin '--set-upstream'' failed (exit-code 128). in Cz\Git\GitRepository->run() (line 584 of /vagrant/www/vendor/czproject/git-php/src/GitRepository.php).
Can you provide any insight?
I am working on laravel framework. I installed this through composer.
$repo = GitRepository::init('/path/to/repo-directory', array(
'--bare', // creates bare repo
));
In this line I get error
"Class 'GitRepository' not found"
I use git-php in Lumen framework with the following code
try{
$git = new Git();
$remote = env('GIT_URL').$request->code;
$local = storage_path('repo')."/".$request->code;
$repo = $git->open($local);
$repo->execute("config", "user.name", "latexbki");
$repo->execute("config", "user.email", "[email protected]");
$filename = $repo->getRepositoryPath() . '/'.$request->file;
file_put_contents($filename, $request->content);
$repo->addFile($filename);
$repo->commit("test adding notes", "--author=latexbki <[email protected]>");
$repo->push(NULL, ['--repo'=>$remote]);
return response()->json(['status'=>"success", 'message'=>"Changes pushed to remote successfully"], 200);
}catch(\Exception $e)
{
$errormessage = "Draft Controller: ".$e->getMessage()." -- in line ".$e->getLine();
return response()->json(['code'=>500, 'status'=>"error", 'message'=>$errormessage], 500);
}
When I run the code, I get the error
Command 'git push --repo 'https://latex.bki%40gmail.com:[email protected]/62c7951c097b4c6fdf2980b4' --end-of-options' failed (exit-code 129). error: unknown option end-of-options
I previously get the same error from addFile and I resolve it by commenting the end-of-option part.
My questions are:
Thank you very much
There is the method hasChanges() which returns true, if there are any changed files.
But I don't see a method which returns what files have been changed.
Am I overlooking something?
Looks like there is no option to clone particular branch.
Is there any plan to add that or should i send a pull request?
I noticed that hasChanges
compares the shell output in order to determine if there are changes
return (strpos($lastLine, 'nothing to commit')) === FALSE;
Some users have other locales installed:
git status [master]
Auf Branch master
Ihr Branch ist auf dem selben Stand wie 'origin/master'.
nichts zu committen, Arbeitsverzeichnis unverändert
nichts zu committen
is the German translation of nothing to commit
which is not beeing detected correctly.
I had a look at the code and did not find a similar string comparison, changing
$lastLine = exec('git status');
// to
$lastLine = exec('LANG=en git status');
works for me, I'm not sure if this works on windows. If you'd like I could open a PR for this - if there are other places where shell output is compared I would like to fix those as well if you could point me there. Updating processCommand
would probably work in most cases if there are any.
My workaround for now is to run my application with LANG=en
.
It seems that git push sends part of the output to stderr.
I think it would be best to add --porcelain to a push command on default.
It was working before. now bitbucket changed their password policy and make it strong with app passwords doesnt allowed.
Hi,
i try to implement some missing features e.g. git log
i use as start
public function getBranches()
{
return $this->extractFromCommand('git branch -a', function($value) {
return trim(substr($value, 1));
});
}
i modified that function in my own class like this:
class OwnGitRepository extends \Cz\Git\GitRepository
{
public function getLog($options="")
{
return $this->extractFromCommand("git log $options", function($$
return trim(substr($value, 0));
});
}
}
but when i print this, i only get last commit as array...sorry, i fetched with --depth=1 so there is only commit, also on command line
can you help me getting log,diff and searches (git log --regex/-G) working?
Hi,
I am new to git process. I have tried to use all functions which are all working fine except commit, addRemote and push commands. I guess, the problem is due to user credentials. Please guide me to set user credentials using this git-php lib. Please help me to move forward for fixing these issues if it is not related to user credentials.
Errors:
git commit Error : "Command 'git commit -m "init commit"' failed."
git add remote Error : "Command 'git remote add "origin" "https://user:[email protected]/user/demo.git\"' failed."
Thanks in advance...
Would be neat to be able to $git->config("user.email")
. Wdyt?
I wanted to clone a repo and create new repo out of it with some minor modifications
Unfortunately there is no method to add all files in one shot for my initial commit. Is there any way i can do that?
Hi, we used to commit from our local system to git repository. overall its working fine.
but, some time I am getting following error,
Cz\Git\GitException: Command 'git commit '1779e4620f28568d37bc6d218359d99f/ed6879fe3ab14763885e8f1c41b2e22b' -m 'Commit : 489b024e153b433394fd83add47be80d_enterprise_1.0.0'' failed (exit-code 128). in [my application path]
it is working fine when i commit following command manually (through putty),
git commit '1779e4620f28568d37bc6d218359d99f/ed6879fe3ab14763885e8f1c41b2e22b' -m 'Commit : 489b024e153b433394fd83add47be80d_enterprise_1.0.0''
When I check status in that directory it will be like in attachement
I don't know what is the problem.
Thanks in advance!!
In Commit 5e82d54 you have added the option --end-of-options
to every command.
In theory this should just work and also the documentation 2.35.1 and 2.25.1 mention this option.
But on both versions specifically the latest for ubuntu 20.04 and 2.35.1 as it's used on Ubuntu 20.04 in github actions always fail for me with the --end-of-options
option enabled.
user@machine:~/testrepo$ git checkout --end-of-options test
error: pathspec '--end-of-options' did not match any file(s) known to git
error: pathspec 'test' did not match any file(s) known to git
user@machine:~/testrepo$ git checkout test
Switched to branch 'test'
user@machine:~/testrepo$ git --version
git version 2.25.1
The above is from my server running ubuntu 20.04 with latest version of git, the exact same behaviour happens in github actions for me.
Edit: fixed wrong link
we can see in code,'path/to/repo'.
// create repo object
$repo = new Cz\Git\GitRepository('/path/to/repo');
I just wanted to know, what is this path? here is my folder structure
dockerproject
|----.git
|----app
|----index.php
|----comspoer.json
|----vendor
|----docker.compose.yml
Do I have to do anything special to see the output of the commands I run. I don't see any output unless there was a fatal exception. Once I got everything worked any output stopped. The only way I know something worked is by checking the files.
Here is my code:
<?php
require __DIR__ . '/vendor/autoload.php';
// create repo object
$repo = new Cz\Git\GitRepository('/home/test_repo/public_html');
$repo->pull('origin');
$repo->checkout('first-draft');
Hey,
i get on $repo->addAllChanges(); "Command 'git add --all ' failed (exit-code 128)"
How i can fix it?
Command 'git add --end-of-options '...' failed (exit-code 128).
Is it possible to checkout a repository and provide the depth
param?
Hi
thank you for trying to bring a great feature into PHP.
Can you tell me is it possible to bring the pirvate repositories clone, git and push with help your library ?
How can I set the email and name of the person pushing to a git repo?
I have an issue with this line:
Line 695 in eed45e3
... on Windows. As described here:
https://www.php.net/manual/en/function.escapeshellarg.php#123718
I now solved it by creating a new class extending GitRepository, overwriting the execute
and processcommand
methods, where I rewrite the escape lines.
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
$cmd[] = $_c . self::escape_win32_argv($value);
} else {
$cmd[] = $_c . escapeshellarg($value);
}
where the escape_win32_argv()
function is from the above mentioned topic at the PHP site.
Hi, this library sounds great for me since i wanna try about managing git repository in php. But i saw there are lots of PR waiting to be merge or issue waiting to be solve..so i wonder is this library ready to use in production environment?
Thanks.
Hi there:
I'm trying to list all the branches from a big repository (arround 520 branches) but the command never ends.
$repo = $git->open(..path..); $branches = $repo->getBranches();
When there is only one remote, the command works fine.
When using 2 remotes, the command never ends (waited for more than 30 minutes).
I even tried to configure pager.branch => false or cat to avoid less output, but without luck.
Using PHP 7.4
The exec() function of PHP is disabled on a shared hosting. I need to use the exec() for Git Hub Web hooks push event on the shared hosting. I need to know if this library use the exec() function.
i wanted a way to check if the repo exists in the git url
Use case:
I dont want to come to third step and fail if repo is not found and do a clean up. Child repo has multiple implementations and the name of child repo is given by the user (chances of typo)
I was thinking if there is any way to verify that the repo is existing and my cli app can read its info (which proves me that the user has valid ssh key).
Basically i wanted to start cloning/downloading the repos after verifying that all the repos are existing and accessible.
I came across this question.
See #9
I see you have a method for getRemoteBranches
which does git branch -r
behind the scenes, but why not also have a method getRemotes
which would do git remote
behind the scenes? It could even take -v
argument optionally...
https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes
public function getRemotes(bool $displayUrls = false)
{
$command = $displayUrls ? 'git remote -v' : 'git remote';
return $this->extractFromCommand($command, function($value) {
return trim(substr($value, 1));
});
}
$git = new CzProject\GitPhp\Git;
$repo = $git->init(__DIR__ . '/directory');
$repo->commit('message');
$repo2 = $git->open(__DIR__ . '/repo2'); // or new GitRepository(__DIR__ . '/repo2')
$repo->run('remote set-branches', 'origin', 'branch-1');
IGit
interfaceGit
with methods:open($directory): GitRepository
init($directory, $params): GitRepository
(replacement for GitRepository::init()
)clone($url, $directory): GitRepository
(replacement for GitRepository::cloneRepository()
)isRemoteUrlReadable($url, $refs): bool
(replacement for GitRepository::isRemoteUrlReadable()
)GitRepository
run()
publicbegin()
& end()
init
, cloneRepository
, isRemoteUrlReadable
extractRepositoryNameFromUrl
& isAbsolute
to new class Helpers
Internals
CliRunner
(default)MemoryRunner
(for tests)@return self
to @return static
in PhpDocsproc_open
instead of exec
$var
name in PhpDocsAll methods in the Cz\Git\GitRepository class that return either $this
or static
annotate self
as their return type. This may cause IDEs (e.g. PhpStorm) to warn about type incompatibility between Cz\Git\GitRepository and extensions of that class.
Given the following extension of \Cz\Git\GitRepository:
<?php
namespace App\Git;
class GitRepository extends \Cz\Git\GitRepository {
/**
* Indicates whether or not there are any unstaged changes at a file/path.
*
* @param string $path
* @return bool
*/
public function hasPathChanges(string $path): bool {
$this->begin();
$resultCode = null;
$output = [];
exec("git diff --exit-code '$path'", $output, $resultCode);
$this->end();
return $resultCode == 1;
}
}
And given the following use of that extension:
<?php
namespace App;
use App\Git\GitRepository;
class VersionControl {
private ?GitRepository $clonedRepo = null;
public function doNeatStuff(Project $project): bool {
# Doing some neat stuff here
GitRepository::cloneRepository($project->getPath(), $this->getClonePath($project))
# ... and some more neatness
}
}
This will cause PhpStorm to raise the following alert for the method call made in VersionControl::doNeatStuff():
Incompatible types: Expected property of type '\App\Git\GitRepository|null', '\Cz\Git\GitRepository' provided
This is contrary to the reality of the matter, as \Cz\Git\GitRepository::cloneRepository() does not explicitly instantiate \Cz\Git\GitRepository
objects, but rather static
objects.
Similarly, non-static methods claim to return self
instances, when they should rather claim to return Cz\Git\IGit
type objects.
Yes, how do we get it. ?
My code structure looks something like this:
use CzProject\GitPhp\Git;
$git = new Git;
$repo = $git->open(base_path()); // base path of local files
$repo->checkout('main');
$repo->pull('origin');
// make some changes to the local files.
// check for changes made
if ($repo->hasChanges()) {
$repo->addAllChanges();
$repo->commit('My Commit Message');
$repo->push(NULL, array('--repo' => 'https://'.env('GITHUB_USER').':'.env('GITHUB_PASS').'@github.com/MyUser/MyRepo.git'));
}
I am able to read the repo, make changes, detect those changes all with success. However when I try to do a commit, I get an error. Command 'git commit -m 'My Commit Message'' failed (exit-code 1).
I've tried setting up the repo to use https and SSH, both fail at the same step. All commands continue to work in the Terminal as expected. Any thoughts on why I would get a failure on the commit command?
Hi there,
Is it possible to set the environment variables for the git commands?
I would like to set GIT_SSH_COMMAND
like here: https://stackoverflow.com/a/29754018
Is this possible? Can you give me any example?
Thanks,
Dom
Is there any way i can get the response which i use to get while executing the command in console?
I am building a cli app for our project and the cli app clones a repo. I want to show the status to the user about the on going process. is there any way i can get that?
I noticed that you change the working directory in your class.
After a successfull action you call your end() method to restore the previous working directory.
But if you throw a GitException if something goes wrong, end() isn't called.
So applications which uses this lib have a wrong cwd after a GitException happend.
I had to manually chdir to my applications main dir.
Hello, I want to upload a project into github.
How can I set my github credentials?
Thank you.
Is there a way to log the output of the Git commands?
I didn't find any function right away that expected a LoggerInterface as a parameter, for example.
I noticed that the outputs from StdOut and StdErr are captured in the RunnerResult object. That would actually be exactly what I need.
But unfortunately only the run() method returns the RunnerResult object, not the commit() and push() methods.
So when I commit, I no longer have a way to access the RunnerResult.
How do I continue here?
Hello
After run composer require czproject/git-php
I can't run composer install
because there is nothing to install or update.
Anyone can help me? Thank you!
Feature request: add worktree functions support
MVP is just the add
function to create a new linked repository directory
Hi, I was planning to hook this up with my other scripts but I wanted to limit the maximum possible size my script will handle.
How can we determine the remote repo size before cloning it?
Thanks.
Hello,
Is it possible to use your package for fork and make pull requests ?
I did not find an example in the readme.
As the CommandProcessor is putting sinqle quotes around the argument that has double quotes (--pretty=fomat:"%H") to "git log", executed by GitRepository::getLastCommitId, the commit ID is then output with surrounding double quotes
This causes CommitId to throw "Invalid commit ID"
CommandProcessor generates this command,
git log '--pretty=format:"%H"' -n 1
which when executed returns
"8d14d508186179480bc35a5c0ab6d9a0f6db863b"
Had it instead been
git log --pretty=format:"%H" -n 1
or
git log '--pretty=format:%H' -n 1
it would work:
8d14d508186179480bc35a5c0ab6d9a0f6db863b
I have a custom method and when I try to checkout in a different branch nothing exists in the project folder
At the end I solve it with exec('git checkout <branch>')
Hello,
I have a private repository in Github: 7system7/test. I would test my connection w/ this code:
use CzProject\GitPhp\Git;
$git = new Git();
$git->isRemoteUrlReadable('https://<username>:<token>@github.com/7system7/test.git'); // false
It always returns false, however the token has permission for everything. What have I wrong?
If I test it the same way in Gitlab or Gitea, it works.
Hi,
I'm having three questions related to consistent command execution. I will post them in this same issue, but in different comments.
GitRepository::run()
vs. exec()
I'd like to ask about the different styles of executing git commands in this library. Some methods of GitRepository
use GitRepository::run()
to execute commands, while others use the exec()
function directly. Am I correct that this is just because different developers were not familiar with how to execute commands in a consistent way (run()
)? If so, can I make a PR that changes all commands to be run via run()
?
Methods that use run()
:
createTag()
removeTag()
renameTag()
merge()
createBranch()
removeBranch()
checkout()
removeFile()
addFile()
addAllChanges()
renameFile()
commit()
hasChanges()
pull()
push()
fetch()
addRemote()
renameRemote()
removeRemote()
setRemoteUrl()
Methods that use exec()
directly:
getLastCommitId()
getCommitMessage()
getCommitData()
Well, actually now that I created this list of methods, I noticed that there's only three methods calling exec()
directly, but then again I still think that it would be cleaner to refactor them to use run()
instead.
I'm using git-php
to generate a changelog for our application. To render the git log, I'm currently parsing the output of $repo->execute('log')
, splitting each line and parsing depending on the first word (commit, author, date, none, etc).
I think it'd be nice if git-php
supported something along these lines, maybe providing an array or a GitLogEntry
object or similar.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.