class GitMaintain::Branch

Constants

ACTION_HELP
ACTION_LIST
ALL_BRANCHES_ACTIONS
NO_CHECKOUT_ACTIONS
NO_FETCH_ACTIONS

Attributes

exists[R]
head[R]
local_branch[R]
remote_branch[R]
remote_ref[R]
stable_base[R]
stable_head[R]
verbose_name[R]
version[R]

Public Class Methods

check_opts(opts) click to toggle source
# File lib/branch.rb, line 112
def self.check_opts(opts)
    if opts[:action] == :push_stable ||
       opts[:action] == :release then
        if opts[:br_suff] != "master" then
            raise "Action #{opts[:action]} can only be done on 'master' suffixed branches"
        end
    end
    if opts[:action] == :delete && opts[:delete_remote] != true then
        if opts[:br_suff] == "master" then
            raise "Action #{opts[:action]} can NOT be done on 'master' suffixed branches"
        end
    end
    opts[:version] = [ /.*/ ] if opts[:version].length == 0
end
delete_epilogue(opts, branches) click to toggle source
# File lib/branch.rb, line 467
def self.delete_epilogue(opts, branches)
    # Compact to remove empty entries
    branches.compact!()

    return if branches.length == 0
    puts "Deleting #{opts[:delete_remote] == true ? "remote" : "local"} branches: #{branches.join(" ")}"
    rep = GitMaintain::confirm(opts, "continue")
    if rep != "y" then
        log(:INFO, "Cancelling")
        return
    end
    if opts[:delete_remote] == true then
        opts[:repo].runGit("push #{opts[:repo].valid_repo} #{branches.map(){|x| ":" + x}.join(" ")}")
    else
        opts[:repo].runGit("branch -D  #{branches.join(" ")}")
    end
end
execAction(opts, action) click to toggle source
# File lib/branch.rb, line 127
def self.execAction(opts, action)
    repo   = Repo::load()
    ci = CI::load(repo)
    opts[:repo] = repo
    opts[:ci] = ci
    brClass = GitMaintain::getClass(self, repo.name)

    if NO_FETCH_ACTIONS.index(action) == nil && opts[:fetch] != false then
        GitMaintain::log(:INFO, "Fetching stable repo")
        repo.stableUpdate(opts[:fetch])
    end

    branchList=[]
    if opts[:manual_branch] == nil then
        unfilteredList = nil
        if ALL_BRANCHES_ACTIONS.index(action) != nil then
            unfilteredList = repo.getStableBranchList()
        else
            unfilteredList = repo.getBranchList(opts[:br_suff])
        end
        branchList = unfilteredList.map(){|br|
            branch = Branch::load(repo, br, ci, opts[:br_suff])
            case branch.is_targetted?(opts)
            when :too_old
                GitMaintain::log(:VERBOSE, "Skipping older v#{branch.version}")
                next
            when :no_match
                GitMaintain::log(:VERBOSE, "Skipping v#{branch.version} not matching" +
                                           opts[:version].to_s())
                next
            end
            branch
        }.compact()
    else
        branchList = [ Branch::load(repo, opts[:manual_branch], ci, opts[:br_suff]) ]
    end

    loop do
        system("clear; date") if opts[:watch] != false

        res=[]

        # Iterate concerned on all branches
        branchList.each(){|branch|
            if NO_CHECKOUT_ACTIONS.index(action) == nil  then
                GitMaintain::log(:INFO, "Working on #{branch.verbose_name}")
                branch.checkout()
            end
            res << branch.send(action, opts)
        }

        # Run epilogue (if it exists)
        begin
            brClass.send(action.to_s() + "_epilogue", opts, res)
        rescue NoMethodError => e
        end

        break if opts[:watch] == false
        sleep(opts[:watch])
        ci.emptyCache()
    end
end
load(repo, version, ci, branch_suff) click to toggle source
# File lib/branch.rb, line 43
def self.load(repo, version, ci, branch_suff)
    repo_name = File.basename(repo.path)
    return GitMaintain::loadClass(Branch, repo_name, repo, version, ci, branch_suff)
end
new(repo, version, ci, branch_suff) click to toggle source
# File lib/branch.rb, line 190
def initialize(repo, version, ci, branch_suff)
    GitMaintain::checkDirectConstructor(self.class)

    @repo          = repo
    @ci            = ci
    @version       = version
    @branch_suff   = branch_suff

    if version =~ /^[0-9]+$/
        @local_branch  = @repo.versionToLocalBranch(@version, @branch_suff)
        @remote_branch = @repo.versionToStableBranch(@version)
        @branch_type = :std
        @verbose_name = "v"+version
    else
        @remote_branch = @local_branch = version
        @branch_type = :user_specified
        @verbose_name = version
    end

    @head          = @repo.runGit("rev-parse --verify --quiet #{@local_branch}")
    @remote_ref    = "#{@repo.stable_repo}/#{@remote_branch}"
    @stable_head   = @repo.runGit("rev-parse --verify --quiet #{@remote_ref}")
    case @branch_type
    when :std
        @stable_base   = @repo.findStableBase(@local_branch)
    when :user_specified
        @stable_base   = @remote_ref
    end
end
push_epilogue(opts, branches) click to toggle source
# File lib/branch.rb, line 343
def self.push_epilogue(opts, branches)
    # Compact to remove empty entries
    branches.compact!()

    return if branches.length == 0

    opts[:repo].runGit("push #{opts[:push_force] == true ? "-f" : ""} "+
                       "#{opts[:repo].valid_repo} #{branches.join(" ")}")
end
push_stable_epilogue(opts, branches) click to toggle source
# File lib/branch.rb, line 409
def self.push_stable_epilogue(opts, branches)
    # Compact to remove empty entries
    branches.compact!()

    return if branches.length == 0
    opts[:repo].runGit("push #{opts[:repo].stable_repo} #{branches.join(" ")}")
end
set_opts(action, optsParser, opts) click to toggle source
# File lib/branch.rb, line 48
def self.set_opts(action, optsParser, opts)
    opts[:base_ver] = 0
    opts[:version] = []
    opts[:commits] = []
    opts[:do_merge] = false
    opts[:push_force] = false
    opts[:no_ci] = false
    opts[:all] = false
    opts[:check_only] = false
    opts[:fetch] = nil
    opts[:watch] = false
    opts[:delete_remote] = false

    optsParser.on("-v", "--base-version [MIN_VER]", Integer, "Older release to consider.") {
        |val| opts[:base_ver] = val}
    optsParser.on("-V", "--version [regexp]", Regexp, "Regexp to filter versions.") {
        |val| opts[:version] << val}

    if  ALL_BRANCHES_ACTIONS.index(action) == nil &&
        action != :merge &&
        action != :delete then
        optsParser.on("-B", "--manual-branch <branch name>", "Work on a specific (non-stable) branch.") {
            |val| opts[:manual_branch] = val}
    end

    if NO_FETCH_ACTIONS.index(action) == nil
        optsParser.on("--[no-]fetch", "Enable/Disable fetch of stable repo.") {
            |val| opts[:fetch] = val}
    end

    case action
    when :cp
        optsParser.banner += "-c <sha1> [-c <sha1> ...]"
        optsParser.on("-c", "--sha1 [SHA1]", String, "Commit to cherry-pick. Can be used multiple time.") {
            |val| opts[:commits] << val}
    when :delete
        optsParser.on("--remote", "Delete the remote staging branch instead of the local ones.") {
            |val| opts[:delete_remote] = true}
    when :merge
        optsParser.banner += "-m <suffix>"
        optsParser.on("-m", "--merge [SUFFIX]", "Merge branch with suffix.") {
            |val| opts[:do_merge] = val}
    when :monitor, :monitor_stable
        optsParser.on("-w", "--watch <PERIOD>", Integer,
                      "Watch and refresh CI status every <PERIOD>.") {
            |val| opts[:watch] = val}
    when :push
        optsParser.banner += "[-f]"
        optsParser.on("-f", "--force", "Add --force to git push (for 'push' action).") {
            |val| opts[:push_force] = val}
    when :push_stable
        optsParser.banner += "[-T]"
        optsParser.on("-T", "--no-ci", "Ignore CI build status and push anyway.") {
            |val| opts[:no_ci] = true}
        optsParser.on("-c", "--check", "Check if there is something to be pushed.") {
            |val| opts[:check_only] = true}
    when :steal
        optsParser.banner += "[-a]"
        optsParser.on("-a", "--all", "Check all commits from master. "+
                                       "By default only new commits (since last successful run) are considered.") {
            |val| opts[:all] = true}
    end
end

Public Instance Methods

checkout() click to toggle source

Checkout the repo to the given branch

# File lib/branch.rb, line 238
def checkout()
    print @repo.runGit("checkout -q #{@local_branch}")
    if $? != 0 then
        raise "Error: Failed to checkout the branch"
    end
end
cp(opts) click to toggle source

Cherry pick an array of commits

# File lib/branch.rb, line 246
def cp(opts)
    opts[:commits].each(){|commit|
        prev_head=@repo.runGit("rev-parse HEAD")
        log(:INFO, "Applying #{@repo.getCommitHeadline(commit)}")
        @repo.runGitInteractive("cherry-pick #{commit}")
        if $? != 0 then
            log(:WARNING, "Cherry pick failure. Starting bash for manual fixes. Exit shell to continue")
                        @repo.runBash()
                end
        new_head=@repo.runGit("rev-parse HEAD")
        # Do not make commit pretty if it was not applied
        if new_head != prev_head
                    make_pretty(commit)
        end
    }
end
create(opts) click to toggle source
# File lib/branch.rb, line 447
def create(opts)
    return if @head != ""
    log(:INFO, "Creating missing #{@local_branch} from #{@remote_ref}")
    @repo.runGit("branch #{@local_branch} #{@remote_ref}")
end
delete(opts) click to toggle source
# File lib/branch.rb, line 453
def delete(opts)
    if opts[:delete_remote] == true then
        msg = "delete remote branch #{@repo.valid_repo}/#{@local_branch}"
    else
        msg = "delete branch #{@local_branch}"
    end
    rep = GitMaintain::confirm(opts, msg)
    if rep == "y" then
        return @local_branch
    else
        log(:INFO, "Skipping deletion")
        return
    end
end
is_targetted?(opts) click to toggle source
# File lib/branch.rb, line 226
def is_targetted?(opts)
    return true if @branch_type == :user_specified
    if @version.to_i < opts[:base_ver] then
        return :too_old
    end
    opts[:version].each() {|regexp|
        return true if @version =~ regexp
    }
    return :no_match
end
list(opts) click to toggle source

List commits in the branch that are no in the stable branch

# File lib/branch.rb, line 292
def list(opts)
    GitMaintain::log(:INFO, "Working on #{@verbose_name}")
    GitMaintain::showLog(opts, @local_branch, @remote_ref)
end
list_stable(opts) click to toggle source

List commits in the stable_branch that are no in the latest release

# File lib/branch.rb, line 298
def list_stable(opts)
    GitMaintain::log(:INFO, "Working on #{@verbose_name}")
    GitMaintain::showLog(opts, @remote_ref, @repo.runGit("describe --abbrev=0 #{@local_branch}"))
end
log(lvl, str) click to toggle source
# File lib/branch.rb, line 222
def log(lvl, str)
    GitMaintain::log(lvl, str)
end
merge(opts) click to toggle source

Merge merge_branch into this one

# File lib/branch.rb, line 304
def merge(opts)
    merge_branch = @repo.versionToLocalBranch(@version, opts[:do_merge])

    # Make sure branch exists
    hash_to_merge = @repo.runGit("rev-parse --verify --quiet #{merge_branch}")
    if $? != 0 then
        log(:INFO, "Branch #{merge_branch} does not exists. Skipping...")
        return
    end

    # See if there is anything worth merging
    merge_base_hash = @repo.runGit("merge-base #{merge_branch} #{@local_branch}")
    if merge_base_hash == hash_to_merge then
        log(:INFO, "Branch #{merge_branch} has no commit that needs to be merged")
        return
    end

    rep = GitMaintain::checkLog(opts, merge_branch, @local_branch, "merge")
    if rep == "y" then
        @repo.runGitInteractive("merge #{merge_branch}")
        if $? != 0 then
            log(:WARNING, "Merge failure. Starting bash for manual fixes. Exit shell to continue")
                        @repo.runBash()
                end
    else
        log(:INFO, "Skipping merge")
        return
    end 
end
monitor(opts) click to toggle source

Monitor the build status on CI

# File lib/branch.rb, line 354
def monitor(opts)
    st = @ci.getValidState(self, @head)
    suff=""
    case st
    when "started"
        suff= " started at #{@ci.getValidTS(self, @head)}"
    end
    log(:INFO, "Status for v#{@version}: " + st + suff)
    if @ci.isErrored(self, st) && opts[:watch] == false
        rep = "y"
        suff=""
        while rep == "y"
            rep = GitMaintain::confirm(opts, "see the build log#{suff}")
            if rep == "y" then
                log = @ci.getValidLog(self, @head)
                tmp = `mktemp`.chomp()
                tmpfile = File.open(tmp, "w+")
                tmpfile.puts(log)
                tmpfile.close()
                system("less -r #{tmp}")
                `rm -f #{tmp}`
            end
            suff=" again"
        end
    end
end
monitor_stable(opts) click to toggle source

Monitor the build status of the stable branch on CI

# File lib/branch.rb, line 417
def monitor_stable(opts)
    st = @ci.getStableState(self, @stable_head)
    suff=""
    case st
    when "started"
        suff= " started at #{@ci.getStableTS(self, @stable_head)}"
    end
    log(:INFO, "Status for v#{@version}: " + st + suff)
end
push(opts) click to toggle source

Push the branch to the validation repo

# File lib/branch.rb, line 335
def push(opts)
    if same_sha?(@local_branch, @repo.valid_repo + "/" + @local_branch) then
        log(:INFO, "Nothing to push")
        return
    end
    return "#{@local_branch}:#{@local_branch}"
end
push_stable(opts) click to toggle source

Push branch to the stable repo

# File lib/branch.rb, line 382
def push_stable(opts)
    if (opts[:no_ci] != true && @NO_CI != true) &&
       @ci.checkValidState(self, @head) != true then
        log(:WARNING, "Build is not passed on CI. Skipping push to stable")
        return
    end

    if same_sha?(@local_branch, @remote_ref) then
        log(:INFO, "Stable is already up-to-date")
        return
    end

    if opts[:check_only] == true then
        GitMaintain::checkLog(opts, @local_branch, @remote_ref, "")
        return
    end

    rep = GitMaintain::checkLog(opts, @local_branch, @remote_ref, "submit")
    if rep == "y" then
        return "#{@local_branch}:#{@remote_branch}"
    else
        log(:INFO, "Skipping push to stable")
        return
    end
end
release(opts) click to toggle source
# File lib/branch.rb, line 443
def release(opts)
    log(:ERROR,"#No release command available for this repo")
end
reset(opts) click to toggle source

Reset the branch to the upstream stable one

# File lib/branch.rb, line 428
def reset(opts)
    if same_sha?(@local_branch, @remote_ref) then
        log(:INFO, "Nothing to reset")
        return
    end

    rep = GitMaintain::checkLog(opts, @local_branch, @remote_ref, "reset")
    if rep == "y" then
        @repo.runGit("reset --hard #{@remote_ref}")
    else
        log(:INFO, "Skipping reset")
        return
    end
end
steal(opts) click to toggle source

Steal upstream commits that are not in the branch

# File lib/branch.rb, line 264
def steal(opts)
    base_ref=@stable_base

    # If we are not force checking everything,
    # try to start from the last tag we steal upto
    if opts[:all] != true then
        sha = @repo.runGit("rev-parse 'git-maintain/steal/last/#{@stable_base}' 2>&1")
        if $? == 0 then
            base_ref=sha
            log(:VERBOSE, "Starting from last successfull run:")
            log(:VERBOSE, @repo.getCommitHeadline(base_ref))
        end
    end

    master_sha=@repo.runGit("rev-parse origin/master")
    res = steal_all(opts, "#{base_ref}..#{master_sha}", true)

    # If we picked all the commits (or nothing happened)
    # Mark the current master as the last checked point so we
    # can just steal from this point on the next run
    if res == true then
        @repo.runGit("tag -f 'git-maintain/steal/last/#{@stable_base}' origin/master")
        log(:VERBOSE, "Marking new last successfull run at:")
        log(:VERBOSE, @repo.getCommitHeadline(master_sha))
    end
end

Private Instance Methods

add_blacklist(commit) click to toggle source
# File lib/branch.rb, line 486
def add_blacklist(commit)
        @repo.runGit("notes append -m \"#{@local_branch}\" #{commit}")
end
confirm_one(opts, commit) click to toggle source
# File lib/branch.rb, line 604
def confirm_one(opts, commit)
            rep=""
            do_cp=false
            puts @repo.getCommitHeadline(commit)
            while rep != "y" do
                    puts "Do you want to steal this commit ? (y/n/b/?)"
        if opts[:no] == true then
            log(:INFO, "Auto-replying no due to --no option")
            rep = 'n'
            break
        else
            rep = STDIN.gets.chomp()
        end
                    case rep
                        when "n"
                        log(:INFO, "Skip this commit")
                                break
                        when "b"
                                log(:INFO, "Blacklisting this commit for the current branch")
                                add_blacklist(commit)
                                break
                        when "y"
                                rep="y"
                                do_cp=true
                                break
                        when "?"
                                puts @repo.runGit("show #{commit}")
        else
                                log(:ERROR, "Invalid answer $rep")
                    puts @repo.runGit("show --format=oneline --no-patch --no-decorate #{commit}")
        end
            end
    return do_cp
end
is_blacklisted?(commit) click to toggle source
# File lib/branch.rb, line 490
def is_blacklisted?(commit)
    @repo.runGit("notes show #{commit} 2> /dev/null").split("\n").each(){|br|
        return true if br == @local_branch
    }
    return false
end
is_in_tree?(commit, src_commit=commit) click to toggle source
# File lib/branch.rb, line 509
def is_in_tree?(commit, src_commit=commit)
        fullhash=@repo.runGit("rev-parse --verify --quiet #{commit}")
        # This might happen if someone pointed to a commit that doesn't exist in our
        # tree.
        if $? != 0 then
        log(:WARNING, "Commit #{src_commit} points to a SHA #{commit} not in tree")
                return false
        end

        # Hope for the best, same commit is/isn't in the current branch
        if @repo.runGit("merge-base #{fullhash} HEAD") == fullhash then
                return true
        end

        # Grab the subject, since commit sha1 is different between branches we
        # have to look it up based on subject.
        subj=@repo.getCommitSubj(commit)
        if $? != 0 then
                return false
        end

        # Try and find if there's a commit with given subject the hard way
        @repo.runGit("log --pretty=\"%H\" -F --grep \"#{subj.gsub("\"", '\\"')}\" "+
                 "#{@stable_base}..HEAD").split("\n").each(){|cmt|
        cursubj=@repo.runGit("log -1 --format=\"%s\" #{cmt}")
        if cursubj = subj then
                return true
                end
        }
        return false
end
is_relevant?(commit) click to toggle source
# File lib/branch.rb, line 541
def is_relevant?(commit)
        # Let's grab the commit that this commit fixes (if exists (based on the "Fixes:" tag)).
        fixescmt=@repo.runGit("log -1 #{commit} | grep -i \"fixes:\" | head -n 1 | "+
                          "sed -e 's/^[ \\t]*//' | cut -f 2 -d ':' | "+
                          "sed -e 's/^[ \\t]*//' -e 's/\\([0-9a-f]\\+\\)(/\\1 (/' | cut -f 1 -d ' '")

        # If this commit fixes anything, but the broken commit isn't in our branch we don't
        # need this commit either.
        if fixescmt != "" then
                  if is_in_tree?(fixescmt, commit) then
              return true
          else
              return false
          end
    end

        if @repo.runGit("show #{commit} | grep -i 'stable@' | wc -l") == "0" then
                return false
        end

        # Let's see if there's a version tag in this commit
        full=@repo.runGit("show #{commit} | grep -i 'stable@'").gsub(/.* #?/, "")

        # Sanity check our extraction
    if full =~ /stable/ then
        return false
    end

    full = @repo.runGit("rev-parse #{full}^{commit}")

        # Make sure our branch contains this version
        if @repo.runGit("merge-base #{@head} #{full}") == full then
                return true
        end

        # Tag is not in history, ignore
        return false
end
make_pretty(orig_commit, commit="") click to toggle source
# File lib/branch.rb, line 497
def make_pretty(orig_commit, commit="")
    orig_sha=@repo.runGit("rev-parse #{orig_commit}")
    msg_commit = (commit.to_s() == "") ? orig_sha : commit

    msg_path=`mktemp`.chomp()
    msg_file = File.open(msg_path, "w+")
        msg_file.puts @repo.runGit("log -1 --format=\"%s%n%n[ Upstream commit #{msg_commit} ]%n%n%b\" #{orig_commit}")
    msg_file.close()
        @repo.runGit("commit -s --amend -F #{msg_path}")
    `rm -f #{msg_path}`
end
pick_one(commit) click to toggle source
# File lib/branch.rb, line 580
def pick_one(commit)
    @repo.runGitInteractive("cherry-pick --strategy=recursive -Xpatience -x #{commit} &> /dev/null")
        return if  $? == 0
    if @repo.runGit("status -uno --porcelain | wc -l") == "0" then
                    @repo.runGit("reset --hard")
        raise CherryPickErrorException.new("Failed to cherry pick commit #{commit}", commit)
            end
            @repo.runGit("reset --hard")
            # That didn't work? Let's try that with every variation of the commit
            # in other stable trees.
    @repo.find_alts(commit).each(){|alt_commit|
                    @repo.runGitInteractive("cherry-pick --strategy=recursive -Xpatience -x #{alt_commit} &> /dev/null")
                    if $? == 0 then
                            return
                    end
                    @repo.runGit("reset --hard")
    }
            # Still no? Let's go back to the original commit and hand it off to
            # the user.
            @repo.runGitInteractive("cherry-pick --strategy=recursive -Xpatience -x #{commit} &> /dev/null")
    raise CherryPickErrorException.new("Failed to cherry pick commit #{commit}", commit)
        return false
end
same_sha?(ref1, ref2) click to toggle source
# File lib/branch.rb, line 709
def same_sha?(ref1, ref2)
    c1=@repo.runGit("rev-parse --verify --quiet #{ref1}")
    c2=@repo.runGit("rev-parse --verify --quiet #{ref2}")
    return c1 == c2

end
steal_all(opts, range, mainline = false) click to toggle source
# File lib/branch.rb, line 701
 def steal_all(opts, range, mainline = false)
     res = true
         @repo.runGit("log --no-merges --format=\"%H\" #{range} | tac").split("\n").each(){|commit|
         res &= steal_one(opts, commit, mainline)
     }
     return res
end
steal_one(opts, commit, mainline=false) click to toggle source
# File lib/branch.rb, line 639
def steal_one(opts, commit, mainline=false)
            msg=''
    orig_cmt=commit

    if mainline == false then
                subj=@repo.getCommitSubj(commit)
        subj.gsub!(/"/, '\"')
                # Let's grab the mainline commit id, this is useful if the version tag
                # doesn't exist in the commit we're looking at but exists upstream.
                orig_cmt=@repo.runGit("log --no-merges --format=\"%H\" -F --grep \"#{subj}\" " +
                              "#{@stable_base}..origin/master | tail -n1")

        if orig_cmt == "" then
            log(:WARNING, "Could not find commit #{commit} in mainline")
        end
    end
    # If the commit doesn't apply for us, skip it
            if is_relevant?(orig_cmt) != true
        return true
            end

    log(:VERBOSE, "Found relevant commit #{@repo.getCommitHeadline(commit)}")
            if is_in_tree?(orig_cmt) == true
                # Commit is already in the stable branch, skip
        log(:VERBOSE, "Commit is already in tree")
        return true
            end

            # Check if it's not blacklisted by a git-notes
            if is_blacklisted?(orig_cmt) == true then
                # Commit is blacklisted
                    log(:INFO, "Skipping 'blacklisted' commit " +
             @repo.getCommitHeadline(orig_cmt))
        return true
            end

    do_cp = confirm_one(opts, orig_cmt)
    return false if do_cp != true

    prev_head=@repo.runGit("rev-parse HEAD")

    begin
                pick_one(commit)
    rescue CherryPickErrorException => e
                    log(:WARNING, "Cherry pick failed. Fix, commit (or reset) and exit.")
                    @repo.runSystem("/bin/bash")
    end
    new_head=@repo.runGit("rev-parse HEAD")

            # If we didn't find the commit upstream then this must be a custom commit
            # in the given tree - make sure the user checks this commit.
            if orig_cmt == "" then
                    msg="Custom"
                    orig_cmt=@repo.runGit("rev-parse HEAD")
                    log(:WARNING, "Custom commit, please double-check!")
                    @repo.runSystem("/bin/bash")
            end
    if new_head != prev_head
                make_pretty(orig_cmt, msg)
    end
end