Guest User

Untitled

a guest
Feb 20th, 2018
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.48 KB | None | 0 0
  1. #!/usr/bin/env perl
  2. # Copyright (C) 2006, Shawn Pearce <spearce@spearce.org>
  3. # This file is licensed under the GPL v2, or a later version
  4. # at the discretion of Linus.
  5.  
  6. package Git;
  7. sub remote_refs {
  8. my ($self, $repo, $groups, $refglobs) = _maybe_self(@_);
  9. my @args;
  10. if (ref $groups eq 'ARRAY') {
  11. foreach (@$groups) {
  12. if ($_ eq 'heads') {
  13. push (@args, '--heads');
  14. } elsif ($_ eq 'tags') {
  15. push (@args, '--tags');
  16. } else {
  17. # Ignore unknown groups for future
  18. # compatibility
  19. }
  20. }
  21. }
  22. push (@args, $repo);
  23. if (ref $refglobs eq 'ARRAY') {
  24. push (@args, @$refglobs);
  25. }
  26.  
  27. my @self = $self ? ($self) : (); # Ultra trickery
  28. my ($fh, $ctx) = Git::command_output_pipe(@self, 'ls-remote', @args);
  29. my %refs;
  30. while (<$fh>) {
  31. chomp;
  32. my ($hash, $ref) = split(/\t/, $_, 2);
  33. $refs{$ref} = $hash;
  34. }
  35. Git::command_close_pipe(@self, $fh, $ctx);
  36. return \%refs;
  37. }
  38.  
  39. use warnings;
  40. use strict;
  41. use Git;
  42.  
  43. my $remote = shift || 'origin';
  44. my $repo = Git->repository();
  45.  
  46. # Build our list of refs.
  47. #
  48. my $remote_refs = ls_refs($repo, $remote);
  49. my $local_refs = ls_refs($repo, $repo->repo_path());
  50. my $remote_HEAD = $remote_refs->{'HEAD'};
  51. my $local_HEAD = $local_refs->{'HEAD'};
  52. delete $remote_refs->{'HEAD'};
  53. delete $local_refs->{'HEAD'};
  54.  
  55. # Execute the fetch for any refs which differ from our own.
  56. # We don't worry about trying to optimize for rewinds or
  57. # exact branch copies as they are rather uncommon.
  58. #
  59. my @to_fetch;
  60. while (my ($ref, $hash) = each %$remote_refs) {
  61. push(@to_fetch, "$ref:$ref")
  62. if (!$local_refs->{$ref} || $local_refs->{$ref} ne $hash);
  63. }
  64. if (@to_fetch) {
  65. git_cmd_try {
  66. $repo->command_noisy('fetch',
  67. '--force',
  68. '--update-head-ok',
  69. $remote, sort @to_fetch);
  70. } '%s failed w/ code %d';
  71. } else {
  72. print "No changed refs. Skipping fetch.\n";
  73. }
  74.  
  75. # See what the remote has HEAD pointing at and update our local
  76. # HEAD to point at some ref which points at the same hash.
  77. # Prefer to keep HEAD the same if possible to avoid HEAD drifting
  78. # between different branches.
  79. # Note that with dumb protocols, we don't get to *know* HEAD implicitly
  80. # with git-ls-remote...
  81. #
  82. git_cmd_try {
  83. my $headref = $repo->command_oneline('symbolic-ref', 'HEAD');
  84. my $HEAD;
  85. if (not $remote_refs->{$headref}) {
  86. $HEAD = 'refs/heads/master';
  87. print "Local HEAD branch disappeared, falling back to refs/heads/master\n";
  88. } elsif ($remote_HEAD and $remote_refs->{$headref} ne $remote_HEAD) {
  89. my %by_hash = map {$remote_refs->{$_} => $_}
  90. grep {m,^refs/heads/,}
  91. sort keys %$remote_refs;
  92. $HEAD = $by_hash{$remote_HEAD};
  93. if ($HEAD) {
  94. print "Setting HEAD to $HEAD ($remote_HEAD)\n";
  95. } else {
  96. print "Remote HEAD ($remote_HEAD) does not match any remote branch\n";
  97. }
  98. }
  99. if ($HEAD) {
  100. $repo->command_noisy('symbolic-ref', 'HEAD', $HEAD);
  101. }
  102. } '%s failed w/ code %d';
  103.  
  104. # Delete any local refs which the server no longer contains.
  105. #
  106. foreach my $ref (keys %$local_refs) {
  107. next if $remote_refs->{$ref};
  108. print "Removing $ref\n";
  109. git_cmd_try {
  110. $repo->command_noisy('update-ref', '-d', $ref, $local_refs->{$ref});
  111. } '%s failed w/ code %d';
  112. }
  113.  
  114. sub ls_refs {
  115. my $repo = shift;
  116. my $name = shift;
  117. my $refs = $repo->remote_refs($name);
  118. my @interesting = grep {
  119. $_ eq 'HEAD' or (/^refs\// and not /\.\./ and not /\^{}$/);
  120. } keys %$refs;
  121.  
  122. my %refs2;
  123. # This funky-looking expression puts @interesting-subset of %$refs
  124. # to %refs2.
  125. @refs2{@interesting} = @{$refs}{@interesting};
  126. \%refs2;
  127. }
Add Comment
Please, Sign In to add comment