Git.pm 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. package SimplyGit::Git;
  2. use strict;
  3. use warnings;
  4. use Log::Log4perl qw(:easy);
  5. use lib ".";
  6. use SimplyGit::Shellex qw(shellex findBin);
  7. use Exporter qw(import);
  8. our @EXPORT_OK = qw(readConfig getStatus returnState addFiles commitChanges pushChanges stashAndReset resetFromUpstream);
  9. sub readConfig {
  10. # This sub is probably not really needed for what I'm trying to do
  11. # git itself already parses this config...but an interesting exercise non the less
  12. # and may be useful later
  13. my $path = shift;
  14. my $logger = shift;
  15. if ( ! -d $path ) {
  16. if ( defined $logger && $logger ne "" ) {
  17. $logger->error("$path doesn't look like a dir, exiting...");
  18. exit 1;
  19. } else {
  20. print "Failed and no logger passed, exiting...\n";
  21. exit 1;
  22. }
  23. }
  24. my $gitConfigPath = $path . "/" . ".git/config";
  25. my $catCmd = findBin("cat",$logger);
  26. my @configLines = split("\n",shellex("$catCmd $gitConfigPath",$logger));
  27. # Key is config header, value is hash ref containing config values
  28. my %gitConfig;
  29. my @valueLines;
  30. my $lineCounter = 0;
  31. foreach my $line ( @configLines ) {
  32. $lineCounter++;
  33. #if ( $line =~ m/\[(.*)\]/ ) {
  34. if ( $line =~ m/\[(.*)\]/ ) {
  35. #$valueLine =~ /\t(.*)\ =\ (.*)$/;
  36. $gitConfig{$1} = "";
  37. }
  38. }
  39. # Tag each line with it's heading
  40. # Only way I could think of that worked to solve how this
  41. # There are almost certainly better ways
  42. # TODO
  43. my @taggedLines;
  44. my $tag = "NULLTAG";
  45. foreach my $line ( @configLines ) {
  46. if ( $line =~ m/\[(.*)\]/ ) {
  47. $tag = $1;
  48. } else {
  49. my $newLine = $tag . $line;
  50. push(@taggedLines,$newLine);
  51. }
  52. }
  53. # Get all of the tagged lines into a hash structure.
  54. foreach my $key ( keys %gitConfig ) {
  55. my %stash;
  56. foreach my $tl ( @taggedLines ) {
  57. if ( $tl =~ m/^($key)/ ) {
  58. $tl =~ s/^($key)//g;
  59. $tl =~ m/^\t(.*)\ \=\ (.*)$/;
  60. my $confKey = $1;
  61. my $confVal = $2;
  62. $stash{$confKey} = $confVal;
  63. }
  64. }
  65. $gitConfig{$key} = \%stash;
  66. }
  67. return %gitConfig;
  68. }
  69. sub getStatus {
  70. my $logger = shift;
  71. my $gitCmd = findBin("git",$logger);
  72. my $status = shellex("$gitCmd status -uall --porcelain",$logger);
  73. chomp $status;
  74. return $status;
  75. }
  76. sub returnState {
  77. my $logger = shift;
  78. my $gitCmd = findBin("git",$logger);
  79. my $currentStatus = getStatus($logger);
  80. my @statusLines = split("\n", $currentStatus);
  81. my @untracked;
  82. my @modified;
  83. my @added;
  84. my @deleted;
  85. foreach my $file ( @statusLines ) {
  86. $file =~ m/^\ {0,1}([A-Z?]{1,2})\ {1,2}(.*)/;
  87. my $fileAttrs = $1;
  88. my $filename = $2;
  89. my @attrs = split("",$fileAttrs);
  90. foreach my $attr ( @attrs ) {
  91. if ( $attr =~ m/\?/ ) {
  92. push(@untracked, $filename) unless grep $_ eq $filename, @untracked;
  93. }
  94. if ( $attr =~ m/[M]/ ) {
  95. push(@modified, $filename) unless grep $_ eq $filename, @modified;
  96. }
  97. if ( $attr =~ m/[A]/ ) {
  98. push(@added, $filename) unless grep $_ eq $filename, @added;
  99. }
  100. if ( $attr =~ m/[D]/ ) {
  101. push(@deleted, $filename) unless grep $_ eq $filename, @deleted;
  102. }
  103. }
  104. }
  105. return ( \@untracked, \@modified, \@added, \@deleted );
  106. }
  107. sub addFiles {
  108. my $filesToAddRef = shift;
  109. my $logger = shift;
  110. my $gitCmd = findBin("git",$logger);
  111. foreach my $file ( @$filesToAddRef ) {
  112. shellex("$gitCmd add $file",$logger);
  113. }
  114. }
  115. # TODO: Possibly worth returning output for commitChanges(), pushChanges(), stashAndReset, even if I'm not using it right now
  116. sub commitChanges {
  117. my $commitMsg = shift;
  118. chomp $commitMsg;
  119. my $logger = shift;
  120. my $gitCmd = findBin("git",$logger);
  121. shellex("$gitCmd commit -m \"$commitMsg\"",$logger);
  122. }
  123. sub pushChanges {
  124. my $logger = shift;
  125. my $gitCmd = findBin("git",$logger);
  126. my $output = shellex("$gitCmd push",$logger);
  127. }
  128. sub stashAndReset {
  129. my $logger = shift;
  130. my $gitCmd = findBin("git",$logger);
  131. shellex("$gitCmd stash",$logger);
  132. my @stashList = split("\n", shellex("$gitCmd stash list",$logger));
  133. my $stashCount = scalar @stashList;
  134. foreach my $stashNum ( 1..$stashCount ) {
  135. shellex("$gitCmd stash drop 0",$logger);
  136. }
  137. # TODO: Depending on use case need to do more here
  138. shellex("$gitCmd rebase",$logger);
  139. }
  140. sub resetFromUpstream {
  141. # git stash and git reset --hard and git pull ? I think
  142. }
  143. sub appendRepoUserConfig {
  144. }