1Git::Repository::TutoriUasle(r3)Contributed Perl DocumenGtiatt:i:oRnepository::Tutorial(3)
2
3
4
6 Git::Repository::Tutorial - Control git from Perl using Git::Repository
7
9 use Git::Repository;
10
11 # do cool stuff with Git, using the following advice
12
14 A Git::Repository object represents an actual Git repository, against
15 which you can run commands.
16
17 Obtain a Git::Repository object from an existing repository
18 If your script is expected to run against a repository in the current
19 directory (like most Git commands), let Git::Repository handle the
20 magic:
21
22 $r = Git::Repository->new();
23
24 If the repository has a working copy (work tree):
25
26 $r = Git::Repository->new( work_tree => $dir );
27
28 If the repository is a bare repository, or you prefer to provide the
29 .git directory location:
30
31 $r = Git::Repository->new( git_dir => $gitdir );
32
33 If the work tree and the git directory are in unrelated locations, you
34 can also provide both:
35
36 $r = Git::Repository->new( work_tree => $dir, git_dir => $gitdir );
37
38 The constructor also accepts an option hash. The various options are
39 detailed in the manual page for Git::Repository::Command.
40
41 Run any git command
42 Git commands can be run against an existing Git::Repository object, or
43 against the class itself (in which case, git will try to deduce its
44 context from the current directory and the environment).
45
46 The pattern for running commands is always the same:
47
48 $r->run( $command => @arguments, \%options );
49
50 The $command and @arguments are identical to those you'd pass to the
51 "git" command-line tool. The options hash contains options, as
52 described in the manual page for Git::Repository::Command.
53
54 Create a new repository
55 Sometime, you'll need to create the Git repository from scratch:
56
57 # git version 1.6.5 and above
58 Git::Repository->run( init => $dir );
59 $r = Git::Repository->new( work_tree => $dir );
60
61 Any git older than 1.6.5 requires the command to be run in the work
62 tree, so we use the "cwd" option:
63
64 # git version 1.5.0.rc1 and above
65 Git::Repository->run( init => { cwd => $dir } );
66 $r = Git::Repository->new( work_tree => $dir );
67
68 # older git versions
69 Git::Repository->run( 'init-db' => { cwd => $dir } );
70 $r = Git::Repository->new( work_tree => $dir );
71
72 Note that the old "create()" method is obsolete (as of Git::Repository
73 1.18, from April 16, 2011) and has been removed (as of Git::Repository
74 1.301, January 21, 2013).
75
76 Clone a repository
77 Cloning works the same way:
78
79 Git::Repository->run( clone => $url => $dir );
80 $r = Git::Repository->new( work_tree => $dir );
81
82 Run a simple command
83 When you don't really care about the output of the command, just call
84 it:
85
86 $r->run( add => '.' );
87 $r->run( commit => '-m', 'my commit message' );
88
89 In case of an error or warning, Git::Repository will "croak()" or
90 "carp()" appropriately.
91
92 Properly quote options
93 It's common to work out the proper string of Git commands needed to
94 achieve your goal in the shell, before actually turning them into calls
95 to "Git::Repository->run".
96
97 Some options might require quoting, to properly get the arguments to
98 Git through the shell:
99
100 # shell
101 $ git log --since='Fri Jul 26 19:34:15 2013 +0200' --grep='report ticket'
102
103 Such quoting is of course not needed with Git::Repository:
104
105 $since = 'Fri Jul 26 19:34:15 2013 +0200';
106 $grep = 'report ticket';
107 my $cmd = $r->command( log => "--since=$since", "--grep=$grep" );
108
109 Be careful with spaces in options
110 For the same reasons as above (individual arguments to "run" or
111 "command" are turned into individual "argv" elements for git,
112 whitespace included), some command-line usages of git need to be
113 slightly reformatted to make them suitable for "run()".
114
115 For example, these two commands have the same effect when run from the
116 shell:
117
118 shell> git checkout -b sometopic
119 shell> git checkout -bsometopic
120
121 In the first case, git receives three arguments in "argv": "checkout",
122 "-b" and "sometopic". In the second case, it receives two arguments:
123 "checkout" and "-bsometopic", and then git recognizes the beginning of
124 the -b option and splits "sometopic" out of the second argument.
125
126 So, in a call such as:
127
128 $command = $repo->run( checkout => "-b$branch_name", { quiet => 0 } );
129
130 If $branch_name contains an initial space character, the call will be
131 equivalent the following shell command:
132
133 shell> git checkout -b\ sometopic
134
135 and git will receive two arguments: "checkout" and "-b sometopic", from
136 which it will split out " sometopic" (note the initial space).
137
138 The space after -b must be removed, as otherwise the code attempts to
139 create a branch called " sometopic", which git rejects.
140
141 Silence warnings for some Git commands
142 Some Git porcelain commands provide additional information on "STDERR".
143 One typical example is "git checkout":
144
145 $ git checkout mybranch
146 Switched to branch 'mybranch'
147
148 The "run()" method of Git::Repository treats all output on "STDERR" as
149 a warning. Therefore, the following code:
150
151 $r->run( checkout => 'mybranch' );
152
153 will output a warning like this one:
154
155 Switched to branch 'mybranch' at myscript.pl line 10.
156
157 In such a case, you can use the "quiet" option to silence the warning
158 for a single command:
159
160 $r->run( checkout => 'mybranch', { quiet => 1 } );
161
162 To silence all warnings, you can pass the "quiet" option during the
163 creation of the original repository object:
164
165 my $r = Git::Repository->new( { quiet => 1 } );
166
167 This is not recommended, as it might hide important information from
168 you.
169
170 Process normal and error output
171 The "run()" command doesn't capture "STDERR": it only warns (or dies)
172 if something was printed on it. To be able to actually capture error
173 output, "command()" must be used.
174
175 my $cmd = $r->command( @cmd );
176 my @errput = $cmd->stderr->getlines();
177 $cmd->close;
178
179 "run()" also captures all output at once, which can lead to unnecessary
180 memory consumption when capturing the output of some really verbose
181 commands.
182
183 my $cmd = $r->command( log => '--pretty=oneline', '--all' );
184 my $log = $cmd->stdout;
185 while (<$log>) {
186 ...;
187 }
188 $cmd->close;
189
190 Of course, as soon as one starts reading and writing to an external
191 process' communication handles, a risk of blocking exists. Caveat
192 emptor.
193
194 Provide input on standard input
195 Use the "input" option:
196
197 my $commit = $r->run( 'commit-tree', $tree, '-p', $parent,
198 { input => $message } );
199
200 Change the environment of a command
201 Use the "env" option:
202
203 $r->run(
204 'commit', '-m', 'log message',
205 { env => {
206 GIT_COMMITTER_NAME => 'Git::Repository',
207 GIT_COMMITTER_EMAIL => 'book@cpan.org',
208 },
209 },
210 );
211
212 Note that Git::Repository::Command does small changes to the
213 environment a command before running it. Specifically, it:
214
215 · deletes "GIT_DIR" and "GIT_WORK_TREE", and sets them to the
216 corresponding values from the current Git::Repository object
217
218 · deletes "TERM"
219
220 · replaces "PATH" with the value of the "env->{PATH}" option
221
222 The easiest way to preserve en environment variable is to pass it with
223 the "env" option, for example:
224
225 $r->run( qw( config --get-colorbool githooks.color true ),
226 { env => { TERM => $ENV{TERM} } } );
227
228 See Git::Repository::Command and System::Command for other available
229 options.
230
231 Ignore the system and global configuration files
232 Git has three levels of configuration files that can change the output
233 of porcelain commands: system ($(prefix)/etc/gitconfig), global
234 ($HOME/.gitconfig and $XDG_CONFIG_HOME/git/config) and local
235 (.git/config inside the repository).
236
237 To ensure the system and global configuration files will be ignored and
238 won't interfere with the expected output of your Git commands, you can
239 add the following keys to the "env" option:
240
241 GIT_CONFIG_NOSYSTEM => 1,
242 XDG_CONFIG_HOME => undef,
243 HOME => undef,
244
245 Ensure the output from Git commands is not localized
246 Since version 1.7.9, Git translates its most common interface messages
247 into the user's language if translations are available and the locale
248 is appropriately set.
249
250 This means that naively parsing the output "porcelain" commands might
251 fail if the program is unexpectedly run under an unexpected locale.
252
253 The easiest way to ensure your Git commands will be run in a "locale-
254 safe" environment, is to set the "LC_ALL" environment variable to "C".
255
256 The brutal way:
257
258 $ENV{LC_ALL} = 'C';
259
260 The temporary way:
261
262 local $ENV{LC_ALL} = 'C';
263
264 The subtle way (restricted to the commands run on a given
265 Git::Repository instance):
266
267 my $r = Git::Repository->new( { env => { LC_ALL => 'C' } } );
268
269 The stealthiest way (restricted to a single command):
270
271 $r->run( ..., { env => { LC_ALL => 'C' } } );
272
273 Ensure the Git commands are run from the current working directory
274 By default, Git::Repository::Command will "chdir()" to the root of the
275 work tree before launching the requested Git command.
276
277 This means that no matter where your program "chdir()" to, commands on
278 the Git::Repository instance will by default be run from the root of
279 the work tree. So, commands such as "add" need to use the "full" path
280 (relative to "GIT_WORK_TREE") of the files to be added.
281
282 The "cwd" option can be used to define where Git::Repository::Command
283 will "chdir()" to. To instruct Git::Repository::Command to not
284 "chdir()" (and therefore run the Git command from the current working
285 directory), set the option to "undef":
286
287 # run from cwd for this command only
288 $r->run( ..., { cwd => undef } );
289
290 # always run git from cwd
291 my $r = Git::Repository->new( { cwd => undef } );
292
293 Finely control when "run()" dies
294 By default, "Git::Repository->run( ... )" dies if the Git command
295 exited with a status code of 128 (fatal error) or 129 (usage message).
296
297 Some commands will throw an error and exit with a status different from
298 the previous two:
299
300 $r->run( checkout => 'does-not-exist' ); # exit status: 1
301
302 The above "run()" call does not die, and output the following warning:
303
304 error: pathspec 'does-not-exist' did not match any file(s) known to git.
305
306 The exit status (as given by "$? >> 8") is 1.
307
308 To force "run()" to die when the Git command exits with status 1, use
309 the "fatal" option (added in version 1.304, May 25, 2013):
310
311 $r->run( checkout => 'does-not-exist', { fatal => 1 } );
312
313 By default, 128 and 129 remain in the list of fatal codes.
314
315 Here are a few examples:
316
317 # set the fatal codes for all call to run() on this object
318 $r = Git::Repository->new( { fatal => [ 1 .. 255 ] } );
319
320 As usual, setting the option to the Git::Repository object will set it
321 for all commands run for it:
322
323 # "!0" is a shortcut for 1 .. 255
324 $r = Git::Repository->new( { fatal => [ "!0" ] } );
325
326 Using negative codes will make these values non-fatal:
327
328 # the above call to new() makes all exit codes fatal
329 # but 3 and 7 won't be fatal for this specific run
330 $r->run( ..., { fatal => [ -3, -7 ] } );
331
332 When the list contains a single item, there is no need to use an array
333 reference:
334
335 # same as [ "!0" ]
336 $r = Git::Repository->new( { fatal => "!0" } );
337
338 # remove 17 from the list of fatal exit codes for this run only
339 $r->run( ..., { fatal => -17 } );
340
341 See Git::Repository::Command for other available options.
342
343 Process the output of git log
344 When creating a tool that needs to process the output of git log, you
345 should always define precisely the expected format using the --pretty
346 option, and choose a format that is easy to parse.
347
348 Assuming git log will output the default format will eventually lead to
349 problems, for example when the user's git configuration defines
350 "format.pretty" to be something else than the default of "medium".
351
352 See also Git::Repository::Plugin::Log for adding to your
353 Git::Repository objects a "log()" method that will parse the log output
354 for you.
355
356 Understanding the various options for git log can make it very simple
357 to obtain a lot of information.
358
359 For example:
360
361 # all tags reachable from $committish
362 my @tags = map {
363 s/^ \((.*)\)/$1/;
364 ( map +( split /: / )[1], grep /^tag: /, split /, / )
365 }
366 $_->run( qw( log --simplify-by-decoration --pretty=%d ), $committish );
367
368 Process the output of git shortlog
369 git shortlog behaves differently when it detects it's not attached to a
370 terminal. In that case, it just tries to read some git log output from
371 its standard input.
372
373 So this oneliner will hang, because git shortlog is waiting for some
374 data from the program connected to its standard input (the oneliner):
375
376 perl -MGit::Repository -le 'print scalar Git::Repository->run( shortlog => -5 )'
377
378 Whereas this one will "work" (as in "immediately return with no
379 output"):
380
381 perl -MGit::Repository -le 'print scalar Git::Repository->run( shortlog => -5, { input => "" } )'
382
383 So, you need to give git shortlog some input (from git log):
384
385 perl -MGit::Repository -le 'print scalar Git::Repository->run( shortlog => { input => scalar Git::Repository->run( log => -5 ) } )'
386
387 If the log output is large, you'll probably be better off with
388 something like the following:
389
390 use Git::Repository;
391
392 # start both git commands
393 my $log = Git::Repository->command('log')->stdout;
394 my $cmd = Git::Repository->command( shortlog => -ens );
395
396 # feed one with the output of the other
397 my $in = $cmd->stdin;
398 print {$in} $_ while <$log>;
399 close $in;
400
401 # and do something with the output
402 print $cmd->stdout->getlines;
403
404 Wrap git in a sudo call
405 If for a given repository you want to wrap all calls to git in a "sudo"
406 call, you can use the "git" option with an array ref:
407
408 my $r = Git::Repository->new( { git => [qw( sudo -u nobody git )] } );
409
410 In this case, every call to git from $r will actually call "sudo -u
411 nobody git".
412
413 Use submodules
414 Because Git::Repository automatically sets the "GIT_DIR" and
415 "GIT_WORK_TREE" environment variables, some "submodule" sub-commands
416 may fail. For example:
417
418 $r->run( submodule => add => $repository => 'sub' );
419
420 will give the following error:
421
422 error: pathspec 'sub' did not match any file(s) known to git.
423
424 To avoid this error, you should enforce the removal of the
425 "GIT_WORK_TREE" variable from the environment in which the command is
426 run:
427
428 $r->run(
429 submodule => add => $repository => 'sub',
430 { env => { GIT_WORK_TREE => undef } }
431 );
432
433 Note that System::Command version 1.04 is required to be able to remove
434 variables from the environment.
435
436 Sort git versions
437 Since version 1.318, Git::Repository lets Git::Version::Compare handle
438 all version comparisons.
439
440 Sorting version numbers is therefore as simple as:
441
442 use Git::Version::Compare qw( cmp_git );
443
444 @sort_verson = sort cmp_git @versions;
445
446 Add specialized methods to your Git::Repository objects
447 Have a look at Git::Repository::Plugin and
448 Git::Repository::Plugin::Log, to learn how to add your own methods to
449 Git::Repository.
450
451 Run code on the output of a git command through callback
452 Sometimes you need to process the output of a command by running a
453 callback on each line of the output.
454
455 # code inspiration:
456 # https://github.com/dolmen/github-keygen/blob/24c501072ba7d890810de3008434c1fe1f757286/release.pl#L178
457
458 my %tree;
459 $r->run( 'ls-tree' => $commit, sub {
460 my ($mode, $type, $object, $file) = split;
461 $tree{$file} = [ $mode, $type, $object ];
462 } );
463
464 Note that the value returned by the callback will be returned as part
465 of the "run()" output, instead of the original line.
466
467 Initialize a test repository with a bundle
468 Instead of creating a test repository using a series of file editions
469 and commits, one can simply import data into the test repository using
470 a bundle. Bundles are created with the "git bundle create" command (see
471 the Git documentation for details).
472
473 First create a temporary repository with the help of Test::Git:
474
475 use Test::Git;
476 my $r = test_repository();
477
478 then import the bundle data in your repository, and collect the
479 references:
480
481 my @refs = $r->run( bundle => 'unbundle', $bundle_file );
482
483 and finally update the references:
484
485 for my $line (@refs) {
486 my ( $sha1, $ref ) = split / /, $line;
487 $r->run( 'update-ref', $ref => $sha1 );
488 }
489
490 Since Git version 1.6.5, it's also possible to clone directly from a
491 bundle (this creates an "origin" remote pointing to the bundle file):
492
493 my $r = test_repository( clone => [ $bundle_file ] );
494
495 A bundle from a recipient repository's point of view is just like a
496 regular remote repository. See the documentation of git bundle for
497 details of what's possible (e.g. incremental bundles).
498
500 Philippe Bruhat (BooK) <book@cpan.org>
501
503 Copyright 2010-2016 Philippe Bruhat (BooK), all rights reserved.
504
506 This program is free software; you can redistribute it and/or modify it
507 under the same terms as Perl itself.
508
509
510
511perl v5.30.0 2019-07-26 Git::Repository::Tutorial(3)