ParaView/Git/Maintain

From KitwarePublic
< ParaView‎ | Git
Jump to: navigation, search


This page documents how to maintain ParaView branches through Git. See our table of contents for more information.

Merging next topics into master

Before you begin, perform initial setup:

1.

2.

$ git clone --recursive git://paraview.org/ParaView.git

3.

$ ./Utilities/SetupForDevelopment.sh

Gatekeeper Review Script

Script used for weekly ParaView Gatekeeper Review.

#!/usr/bin/env python
import subprocess
import sys
import re
 
#------------------------------------------------------------------------------
class UserCancelled(Exception):
  def __str__(self):
    return "Cancelled by user"
 
pv_only = re.compile("^\\s*([a-zA-Z0-9_-]+)\\s*\|?\\s*$");
pv_and_vtk = re.compile("^\\s*([a-zA-Z0-9_-]+)\\s*|\\s*VTK\\s*$");
 
def execute(command, **kwargs):
  no_echo = kwargs.get("no_echo")
  if not no_echo:
    print "> %s" % command
  process = subprocess.Popen(command, shell=True,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.STDOUT)
  output,_ =  process.communicate()
  if output and not no_echo:
    print "  ------------------------------------------------------------------------------"
    for part in output.splitlines():
      print "  | %s" % part
    print "  ------------------------------------------------------------------------------"
  if process.returncode:
    raise subprocess.CalledProcessError(command, process.returncode)
  return output.strip()
 
def execute_vtk(command, **kwargs):
  return execute("cd VTK && %s" % command, **kwargs)
 
def check(text):
  if raw_input("\n> %s : (y/n) : " % text) != 'y':
    raise UserCancelled()
 
#def merge_paraview_topic(name):
#  execute("git log --oneline --decorate --graph origin/master..stage/%s" % name)
#  check("Merge %s into ParaView?" % name)
#  execute("ssh git@paraview.org stage ParaView merge -b master %s" % name)
#
#def merge_paraview_vtk_topic(name):
#  execute("cd VTK && git log --oneline --decorate --graph pvvtk/pv-master..pvvtk/%s" % name)
#  check("Merge %s into PVVTK?" % name)
#  execute("ssh git@paraview.org stage PVVTK merge -b pv-master %s" % name)
#  merge_paraview_topic(name)
 
def git_reachable(shaA, shaB):
  "Returns true when shaB is reachable from shaA i.e. shaA is ancestor of shaB"
  # based on logic from:
  # http://stackoverflow.com/a/3006203
  merge_base = execute("git merge-base %s %s" % (shaB, shaA), no_echo=True)
  rev_parse = execute("git rev-parse --verify %s" % shaA, no_echo=True)
  return merge_base == rev_parse
 
def git_vtk_reachable(shaA, shaB):
  "Returns true when shaB is reachable from shaA i.e. shaA is ancestor of shaB"
  # based on logic from:
  # http://stackoverflow.com/a/3006203
  merge_base = execute_vtk("git merge-base %s %s" % (shaB, shaA), no_echo=True)
  rev_parse = execute_vtk("git rev-parse --verify %s" % shaA, no_echo=True)
  return merge_base == rev_parse
 
def interactive_merge(topic, vtk_sha):
  """Merge a ParaView topic interactively."""
  print "--------------------------------------------------"
  print "Topic:", topic
  execute("git log --oneline --decorate --graph origin/master..stage/%s" % topic)
  try:
    if vtk_sha:
      check("Merge '%s' into ParaView (+VTK)?" % topic)
    else:
      check("Merge '%s' into ParaView?" % topic)
  except UserCancelled as e:
    print " ", e, ", skipping..."
    return False
  if vtk_sha:
    # this topic has a VTK change. Locate the VTK topic that brings in this
    # change. Because people never name the two topic the same, we have to do
    # some extra juggling here.
 
    # find all topics on pvvtk that this vtk_sha is available in.
    vtk_topics = execute_vtk("git branch --contains=%s -r | grep pvvtk | sed -e 's|pvvtk/||' | sort" % vtk_sha, no_echo=True)
    vtk_topics = vtk_topics.split()
    if not "master" in vtk_topics:
      raise RuntimeError, "VTK topic not merged into vtk-master. Cannot proceed with the merge."
    vtk_topics.remove("master")
    vtk_topics.remove("pv-next")
    try:
      vtk_topics.remove("pv-master")
    except ValueError:
      pass
    try:
      vtk_topics.remove("nightly-pv-next")
    except ValueError:
      pass
 
    if len(vtk_topics) > 1:
      # ask the user which topic to merge.
      print "  Possible VTK topics for SHA-1 ", vtk_sha
      for index,vtk_topic in enumerate(vtk_topics):
        print " ", index,":", vtk_topic
      choice = int(raw_input("  Pick VTK Topic (0-%d): " % (len(vtk_topics)-1)))
      if choice >= 0 and choice < len(vtk_topics):
        # narrow down the available topics to the one chosen by the user.
        vtk_topics = [vtk_topics[choice]]
      else:
        raise RuntimeError, "Invalid VTK topic chosen %d" % choice
    elif len(vtk_topics) == 1:
      try:
        check(" - Merge vtk_topic '%s'" % vtk_topics[0])
      except UserCancelled:
        return False
 
    # at this point vtk_topics must have only 1 topic of interest.
    if len(vtk_topics) != 1:
      raise RuntimeError, "No VTK topic found/picked for ", vtk_sha
    # warn the user if the vtk_topic has more commits than the one the ParaView topic refers to.
    vtk_topic_head_sha = execute_vtk("git show --raw pvvtk/%s | head -n1 | sed -e 's|commit ||'" % vtk_topics[0], no_echo=True)
    if vtk_topic_head_sha != vtk_sha:
      print "WARNING: VTK topic '%s' has more commits than those refered by ParaView topic" % vtk_topics[0]
      try:
        check("Are you sure you want to merge it?")
      except UserCancelled as e:
        print " ", e, ", skipping..."
        return False
    execute("ssh git@paraview.org stage PVVTK merge -b pv-master %s" % vtk_topics[0])
  execute("ssh git@paraview.org stage ParaView merge -b master %s" % topic)
  print "Merge successful!!!"
  return True
 
#------------------------------------------------------------------------------
print """
                      (                                            
                      )\ )                                         
                     (()/(    )  (       )   )   (     (   (  (    
                      /(_))( /(  )(   ( /(  /((  )\   ))\  )\))(   
                     (_))  )(_))(()\  )(_))(_))\((_) /((_)((_)()\  
                     | _ \((_)_  ((_)((_)_ _)((_)(_)(_))  _(()((_) 
                     |  _// _` || '_|/ _` |\ V / | |/ -_) \ V  V / 
                     |_|  \__,_||_|  \__,_| \_/  |_|\___|  \_/\_/  """
print """
   _____       _       _                               _____            _               
  / ____|     | |     | |                             |  __ \          (_)              
 | |  __  __ _| |_ ___| | _____  ___ _ __   ___ _ __  | |__) |_____   ___  _____      __
 | | |_ |/ _` | __/ _ | |/ / _ \/ _ | '_ \ / _ | '__| |  _  // _ \ \ / | |/ _ \ \ /\ / /
 | |__| | (_| | ||  __|   |  __|  __| |_) |  __| |    | | \ |  __/\ V /| |  __/\ V  V / 
  \_____|\__,_|\__\___|_|\_\___|\___| .__/ \___|_|    |_|  \_\___| \_/ |_|\___| \_/\_/  
                                    | |                                                 
                                    |_|                                                 
"""
 
print"""                   **** LOCAL CHANGES MAY BE OVERWRITTEN !!! **** """
print"""                   **** LOCAL CHANGES MAY BE OVERWRITTEN !!! **** """
print"""                   **** LOCAL CHANGES MAY BE OVERWRITTEN !!! **** """
print"""                   **** LOCAL CHANGES MAY BE OVERWRITTEN !!! **** \n\n"""
 
#------------------------------------------------------------------------------
print "Preparing repository for Gatekeeper Review..."
# Ensure all "core" remotes are up-to-date.
execute("git fetch origin -p")
execute("git fetch stage -p")
execute_vtk("git fetch origin -p")
execute_vtk("git fetch pvvtk -p")
 
#------------------------------------------------------------------------------
# Locate all topics merged into next that are currently on stage.
topics = execute("git branch -r --merged origin/nightly-next | grep stage | sed -e 's|stage/||' | sort", no_echo=True)
topics = topics.split()
try:
  topics.remove("master");topics.remove("next")
except ValueError:
  pass
 
#------------------------------------------------------------------------------
# For each topic, determine if is changes VTK.
# A topic changes VTK if the VTK SHA it refers to is not reachable form the
# VTK SHA in master.
master_vtk_ref = execute("git ls-tree origin/master VTK | awk '{print $3}'", no_echo=True)
vtk_topics_map = {}
for topic in topics:
  topic_vtk_ref = execute("git ls-tree stage/%s VTK | awk '{print $3}'" % topic , no_echo=True)
  already_in_master = git_vtk_reachable(topic_vtk_ref, master_vtk_ref)
  if already_in_master:
    vtk_topics_map[topic] = None
  else:
    vtk_topics_map[topic] = topic_vtk_ref
 
#------------------------------------------------------------------------------
# Print some status messages for the human.
print ""
print "---------------------------------------------"
print "Topics in next that can be merged: "
for topic in topics:
  if vtk_topics_map[topic]:
    print "(VTK)  ", topic
  else:
    print "       ", topic
print ""
print ""
 
#------------------------------------------------------------------------------
# Interactively merge the topics.
topics_merged = []
for topic in topics:
  if interactive_merge(topic, vtk_topics_map[topic]):
    topics_merged.append(topic)
 
#------------------------------------------------------------------------------
check("Wrapup gatekeeper review?")
execute("git fetch origin -p")
execute("git fetch stage -p")
execute_vtk("git fetch origin -p")
execute_vtk("git fetch pvvtk -p")
 
# merge pvvtk/pv-master into origin/master
execute_vtk("git checkout -f origin/master")
execute_vtk("git merge --no-ff pvvtk/pv-master")
execute_vtk("git push gerrit HEAD:master")
 
# reset pv-next.
execute_vtk("git checkout -f pvvtk/pv-master")
# dfff5bee7e6dd05e3b763dde829841766679056d is the pv-next deny commit.
execute_vtk("git merge --no-ff dfff5bee7e6dd05e3b763dde829841766679056d -m 'Merge pv-master into pv-next'")
execute_vtk("git push -f pvvtk HEAD:pv-next")
 
# reset next.
# first get the list of topics merged in next that will get unmerged.
dangling_topics = execute("git branch -r --merged stage/next | grep stage | sed -e 's|stage/||' | sort", no_echo=True)
dangling_topics = dangling_topics.split()
try:
  dangling_topics.remove("master") 
except ValueError:
  pass
try:
  dangling_topics.remove("next") 
except ValueError:
  pass
execute("git checkout -f origin/master")
execute("git merge --no-ff aa525d5d662ea6c7036e47a07e4c8a146a773e5f -m 'Merge master into next'")
execute("git push -f origin HEAD:next")
 
print ""
print ""
print "SUMMARY"
 
print "---------------------------------------------"
print "Topics merged into master: "
for topic in topics_merged:
  if vtk_topics_map[topic]:
    print "(VTK)  ", topic
  else:
    print "       ", topic
print ""
print ""
print "---------------------------------------------"
print "Topics reverted from next: "
for topic in dangling_topics:
  print " ", topic

Miscellaneous Commands

  • Show branches merged in next or master on stage
$ git fetch stage -p
$ git branch -r --merged stage/next | grep stage
$ git branch -r --merged stage/master | grep stage
  • Find the SHA1 for the VTK submodule that a branch is referring to.
$ git ls-tree <branchname> VTK | awk '{print $3}'