class Object

Constants

BACKUP_SUFFIX
G
MAX
PATCH_REMAIN_SUFFIX
PREFIX

定数

TMP_SUFFIX

Public Instance Methods

_tryCommit(stash, mode, commitMessage, &onFail) click to toggle source
# File lib/git/stash/commit.rb, line 137
def _tryCommit(stash, mode, commitMessage, &onFail)
  root = BranchFactory::find stash.name.match(/^#{PREFIX}\/(.+)@.+$/)[1]
  stash.commit(mode, commitMessage){
    # commit --patchのキャンセル時ここに来る
    root.checkout
    $g.backup.delete
    onFail.call
  }

  if Cmd::changesCount != '0'
    remain = DetachBranch.new "#{stash.name}-#{PATCH_REMAIN_SUFFIX}", stash.name
    remain.commit Branch::CommitMode::ALL, <<-EOS
patch-remain from #{Cmd::revision stash.name}: #{hash}

*** patch remain ***
'stash-commit --patch' working patch remain commit.

please fix conflicts without '#{stash.name}' contents
EOS
    $g.patch = remain
  end

  return true
end
createBackup(_branch) click to toggle source

# File lib/git/stash/commit.rb, line 122
def createBackup(_branch)
  retBackup = DetachBranch.new Cmd::stashName(_branch, BACKUP_SUFFIX), _branch
  branch = BranchFactory::find _branch
  retBackup.commit Branch::CommitMode::ALL, <<-EOS
backup from #{_branch}: #{Cmd::revision _branch}

*** backup commit ***
'stash-commit --to' working backup commit
EOS
  branch.cherryPickNoCommit retBackup.name
  branch.reset # cancel 'git add'

  retBackup
end
main(argv) click to toggle source
# File lib/git/stash/commit.rb, line 562
def main(argv)
  hash = Cmd::revision
  branch = Cmd::branchName
  title = Cmd::title

  commitMessage = "WIP on #{branch}: #{hash} #{title}" # default
  to = nil
  from = nil
  rebase = nil
  commit = Commit::ALL
  renameOld = nil
  renameNew = nil

  listup = false
  listupAll = false

  # parse argv
  # ----------
  itArgv = ArgvIterator.new(argv)
  while itArgv.next? do
    arg = itArgv.next
    case arg
    when '-m', '--message'
      commitMessage = itArgv.next
    when '--to'
      to = itArgv.next
    when '--from'
      from = itArgv.next
    when '-a', '--all'
      commit = Commit::ALL
      listupAll = true
    when '-p', '--patch'
      commit = Commit::PATCH
    when '--continue'
      rebase = Rebase::CONTINUE
    when '--skip'
      rebase = Rebase::SKIP
    when '--abort'
      rebase = Rebase::ABORT
    when '--rename'
      renameOld = itArgv.next
      renameNew = itArgv.next
    when '-l', '--list'
      listup = true
    when 'help'
      usage
      Kernel.exit true
    when '-d', '--debug'
      $debugMode = true
    else
      puts "* error: unknown option:#{arg}"
      usage
      raise ''
    end
  end

  # --list [--all]
  if listup
    Cmd::listup branch, listupAll
    Kernel.exit true
  end

  # --continue | --skip | --abort
  # -----------------------------
  if rebase != nil
    begin
      raise '' if !validateRebase
      case rebase
      when Rebase::CONTINUE
        raise '' if !tryStashCommitContinue branch
      when Rebase::SKIP
        raise '' if !tryStashCommitSkip branch
      when Rebase::ABORT
        raise '' if !tryStashCommitAbort branch
      end
      return
    rescue => e
      puts "* failed: stash-commit #{rebase}"
      raise e
    end
  end

  # --rename
  # --------
  if renameOld != nil
    begin
      raise '' if !validateRename branch, renameOld, renameNew
      raise '' if !tryStashCommitRename branch, renameOld, renameNew
      return
    rescue => e
      puts '* failed: stash-commit --rename'
      raise e
    end
  end

  # --from | --to
  # -------------
  if from != nil
    begin
      raise '' if !validateFromTo from or !validateStashCommitFrom branch
      raise '' if !tryStashCommitFrom branch, from
      return
    rescue => e
      puts '* failed: stash-commit --from (index | name)'
      raise e
    end
  elsif to != nil
    # --to 指定がある時
    begin
      raise '' if !validateFromTo to or !validateStashCommitTo branch
      raise '' if !tryStashCommitToGrow branch, to, commitMessage, commit
      return
    rescue => e
      puts '* failed: stash-commit --to (index | name)'
      raise e
    end
  else
    # --to 指定がない時
    begin
      raise '' if !validateStashCommitTo branch
      (MAX+1).times do |i|
        if i == MAX
          puts '* error: branch is too many'
          raise ''
        end

        stashBranch = Cmd::stashName branch, i
        if Cmd::branchExist? stashBranch
          puts "\"#{stashBranch}\" is already exist"
          next
        end

        raise '' if !tryStashCommitTo stashBranch, commitMessage, commit
        return
      end
    rescue => e
      puts '* failed: stash-commit'
      raise e
    end
  end

  raise 'logic error' # ここには来ないはず
end
os() click to toggle source
# File lib/git/stash/sclib/util.rb, line 3
def os
  @os ||= (
    host_os = RbConfig::CONFIG['host_os']
    case host_os
    when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
      :windows
    when /darwin|mac os/
      :macosx
    when /linux/
      :linux
    when /solaris|bsd/
      :unix
    else
      :unknown
    end
  )
end
tryCommitAll(stash, commitMessage, &onFail) click to toggle source
# File lib/git/stash/commit.rb, line 161
def tryCommitAll(stash, commitMessage, &onFail)
  _tryCommit(stash, Branch::CommitMode::ALL, commitMessage){onFail.call}
end
tryCommitPatch(stash, commitMessage, &onFail) click to toggle source
# File lib/git/stash/commit.rb, line 164
def tryCommitPatch(stash, commitMessage, &onFail)
  _tryCommit(stash, Branch::CommitMode::PATCH, commitMessage){onFail.call}
end
tryStashCommitAbort(branch) click to toggle source
# File lib/git/stash/commit.rb, line 479
def tryStashCommitAbort(branch)
  if $g.tmp or $g.patch
    return false if !tryStashCommitAbortTo $g.tmp, $g.patch
    $g.backup.delete if $g.backup
  else
    return false if !tryStashCommitAbortFrom branch
  end

  return true
end
tryStashCommitAbortFrom(branch) click to toggle source
# File lib/git/stash/commit.rb, line 464
def tryStashCommitAbortFrom(branch)
  # tmpが無いので、rebase中の時のみ継続
  return false if !Cmd::rebaseInProgress?

  rootMatch = branch.match(/.+rebasing #{PREFIX}\/(.+)@.+\)$/)
  return false if !rootMatch
  return false if !Cmd::execRet 'git rebase --abort'

  # ここまでくれば安心
  root = BranchFactory::find rootMatch[1]
  root.checkout

  return true
end
tryStashCommitAbortTo(tmp, patch) click to toggle source

# File lib/git/stash/commit.rb, line 429
def tryStashCommitAbortTo(tmp, patch)
  if !$g.backup
    puts "stop, '#{BACKUP_SUFFIX}' is not found, from starting stash-commit --to"
    return false
  end

  # rebase --abort前かもしれない
  Cmd::exec 'git rebase --abort' if Cmd::rebaseInProgress?

  if tmp
    root = BranchFactory::find tmp.name.match(/^#{PREFIX}\/(.+)@.+-#{TMP_SUFFIX}$/)[1]
    root.checkout
    tmp.delete
  end
  if patch
    root = BranchFactory::find patch.name.match(/^#{PREFIX}\/(.+)@.+-#{PATCH_REMAIN_SUFFIX}$/)[1]
    root.checkout
    patch.delete

    # もしかしたらtmpとして削除済み
    patchParent = BranchFactory::find patch.name.match(/^(#{PREFIX}\/.+)-#{PATCH_REMAIN_SUFFIX}$/)[1]
    if patchParent
      patchParent.delete
    end
  end

  # ここまでくれば安心
  root = BranchFactory::find $g.backup.name.match(/^#{PREFIX}\/(.+)@#{BACKUP_SUFFIX}$/)[1]
  root.checkout
  root.cherryPickNoCommit $g.backup.name
  root.reset # cancel 'git add'

  return true
end
tryStashCommitContinue(branch) click to toggle source
# File lib/git/stash/commit.rb, line 341
def tryStashCommitContinue(branch)
  if $g.tmp or $g.patch
    return false if !tryStashCommitContinueTo $g.tmp, $g.patch
    $g.backup.delete if $g.backup
  else
    return false if !tryStashCommitContinueFrom branch
  end

  return true
end
tryStashCommitContinueFrom(branch) click to toggle source
# File lib/git/stash/commit.rb, line 321
def tryStashCommitContinueFrom(branch)
  # tmpが無いので、rebase中の時のみ継続
  return false if !Cmd::rebaseInProgress?

  stashMatch = branch.match(/.+rebasing (#{PREFIX}\/.+)\)$/)
  rootMatch = branch.match(/.+rebasing #{PREFIX}\/(.+)@.+\)$/)
  return false if !stashMatch
  return false if !Cmd::execRet 'git rebase --continue'

  # ここまでくれば安心
  stash = BranchFactory::find stashMatch[1]
  root = BranchFactory::find rootMatch[1]
  revision = Cmd::revision root.name
  root.rebase stash.name
  stash.delete
  root.reset revision

  return true
end
tryStashCommitContinueTo(tmp, patch) click to toggle source

# File lib/git/stash/commit.rb, line 270
def tryStashCommitContinueTo(tmp, patch)
  # rebase --continue前かもしれない
  Cmd::exec('git rebase --continue') if Cmd::rebaseInProgress?

  if patch
    root = BranchFactory::find patch.name.match(/^#{PREFIX}\/(.+)@.+-#{PATCH_REMAIN_SUFFIX}$/)[1]
    # rebase --skip後かもしれない
    if Cmd::sameBranch? patch.name, root.name
      puts "stop, '#{PATCH_REMAIN_SUFFIX}' rebase --skip found, from starting stash-commit --patch"
      raise ''
    end
    # rebase --abort後かもしれない
    if !Cmd::parentChildBranch? patch.name, root.name
      patch.rebaseOnto root.name, "#{patch.name}~"
    end
  end
  if tmp
    stash = BranchFactory::find tmp.name.match(/^(#{PREFIX}\/.+)-#{TMP_SUFFIX}$/)[1]
    # rebase --skip後かもしれない
    if Cmd::sameBranch? tmp.name, stash.name
      puts "stop, '#{TMP_SUFFIX}' rebase --skip found, from starting stash-commit --to"
      raise ''
    end
    # rebase --abort後かもしれない
    if !Cmd::parentChildBranch? tmp.name, stash.name
      tmp.rebaseOnto stash.name, "#{tmp.name}~"
    end
  end

  # ここまでくれば安心
  if tmp
    root = BranchFactory::find tmp.name.match(/^#{PREFIX}\/(.+)@.+-#{TMP_SUFFIX}$/)[1]
    stash = BranchFactory::find tmp.name.match(/^(#{PREFIX}\/.+)-#{TMP_SUFFIX}$/)[1]

    tmp.rebase stash.name
    stash.rebase tmp.name
    tmp.delete
    root.checkout
  end
  if patch
    root = BranchFactory::find patch.name.match(/^#{PREFIX}\/(.+)@.+-#{PATCH_REMAIN_SUFFIX}$/)[1]
    revision = Cmd::revision root.name

    root.rebase patch.name
    patch.delete
    root.reset revision
  end

  return true
end
tryStashCommitFrom(_branch, from) click to toggle source

# File lib/git/stash/commit.rb, line 252
def tryStashCommitFrom(_branch, from)
  stash = BranchFactory::find (Cmd::stashName _branch, from)
  branch = BranchFactory::find _branch

  baseHash = Cmd::mergeBaseHash branch.name, stash.name
  stash.rebaseOnto branch.name, baseHash

  # ここまでくれば安心
  revision = Cmd::revision branch.name
  branch.rebase stash.name
  stash.delete
  branch.reset revision

  return true
end
tryStashCommitRename(branch, renameOld, renameNew) click to toggle source

# File lib/git/stash/commit.rb, line 492
def tryStashCommitRename(branch, renameOld, renameNew)
  Cmd::stashCommitRename renameOld, renameNew
end
tryStashCommitSkip(branch) click to toggle source
# File lib/git/stash/commit.rb, line 416
def tryStashCommitSkip(branch)
  if $g.tmp or $g.patch
    return false if !tryStashCommitSkipTo $g.tmp, $g.patch
    $g.backup.delete if $g.backup
  else
    return false if !tryStashCommitSkipFrom branch
  end

  return true
end
tryStashCommitSkipFrom(branch) click to toggle source
# File lib/git/stash/commit.rb, line 398
def tryStashCommitSkipFrom(branch)
  # tmpが無いので、rebase中の時のみ継続
  return false if !Cmd::rebaseInProgress?

  stashMatch = branch.match(/.+rebasing (#{PREFIX}\/.+)\)$/)
  rootMatch = branch.match(/.+rebasing #{PREFIX}\/(.+)@.+\)$/)
  return false if !stashMatch
  return false if !Cmd::execRet 'git rebase --skip'

  # ここまでくれば安心
  stash = BranchFactory::find stashMatch[1]
  root = BranchFactory::find rootMatch[1]
  root.rebase stash.name
  stash.delete

  return true
end
tryStashCommitSkipTo(tmp, patch) click to toggle source

# File lib/git/stash/commit.rb, line 354
def tryStashCommitSkipTo(tmp, patch)
  # rebase --skip前かもしれない
  Cmd::exec('git rebase --skip') if Cmd::rebaseInProgress?

  if patch
    root = BranchFactory::find patch.name.match(/^#{PREFIX}\/(.+)@.+-#{PATCH_REMAIN_SUFFIX}$/)[1]
    # rebase --continue後かもしれない
    if Cmd::parentChildBranch? patch.name, root.name
      puts "stop, '#{PATCH_REMAIN_SUFFIX}' rebase --continue found, from starting stash-commit --patch"
      raise ''
    end
    # rebase --abort後はスルー
  end
  if tmp
    stash = BranchFactory::find tmp.name.match(/^(#{PREFIX}\/.+)-#{TMP_SUFFIX}$/)[1]
    # rebase --continue後かもしれない
    if Cmd::parentChildBranch? tmp.name, stash.name
      puts "stop, '#{TMP_SUFFIX}' rebase --continue found, from starting stash-commit --to"
      raise ''
    end
    # rebase --abort後はスルー
  end

  # ここまでくれば安心
  if tmp
    root = BranchFactory::find tmp.name.match(/^#{PREFIX}\/(.+)@.+-#{TMP_SUFFIX}$/)[1]
    root.checkout
    tmp.delete # skipなので捨てる
  end
  if patch
    root = BranchFactory::find patch.name.match(/^#{PREFIX}\/(.+)@.+-#{PATCH_REMAIN_SUFFIX}$/)[1]
    root.checkout
    patch.delete # skipなので捨てる

    # もしかしたらtmpとして削除済み
    patchParent = BranchFactory::find patch.name.match(/^(#{PREFIX}\/.+)-#{PATCH_REMAIN_SUFFIX}$/)[1]
    if patchParent
      patchParent.delete
    end
  end

  return true
end
tryStashCommitTo(stashBranch, commitMessage, commit, reset=true, backup=true) click to toggle source
# File lib/git/stash/commit.rb, line 201
def tryStashCommitTo(stashBranch, commitMessage, commit, reset=true, backup=true)
  rootBranch = stashBranch.match(/^#{PREFIX}\/(.+)@.+$/)[1]
  stash = Branch::new stashBranch, rootBranch
  tryStashCommitToInternal stash, commitMessage, commit, reset, backup
end
tryStashCommitToGrow(branch, to, commitMessage, commit) click to toggle source
# File lib/git/stash/commit.rb, line 207
def tryStashCommitToGrow(branch, to, commitMessage, commit)
  stashBranch = Cmd::stashName branch, to
  root = BranchFactory::find stashBranch.match(/^#{PREFIX}\/(.+)@.+$/)[1]

  $g.backup = createBackup root.name

  if !Cmd::branchExist? stashBranch
    # 新規作成
    stash = Branch.new stashBranch, root.name
    return false if !tryStashCommitToInternal stash, commitMessage, commit, true, false
  else
    # 存在してるので、そのブランチへ追加する
    # 一端新規作成し
    tmp = DetachBranch.new "#{stashBranch}-#{TMP_SUFFIX}", root.name
    return false if !tryStashCommitToInternal tmp, commitMessage, commit, false, false

    stash = BranchFactory::find stashBranch

    # rebaseで追加
    tmp.rebase stash.name
    stash.rebase tmp.name
    tmp.delete

    root.checkout

    case commit
    when Commit::ALL
      # no-op
    when Commit::PATCH
      if $g.patch
        revision = Cmd::revision root.name
        root.rebase $g.patch.name
        $g.patch.delete
        root.reset revision
      end
    end
  end

  $g.backup.delete

  return true
end
tryStashCommitToInternal(stash, commitMessage, commit, reset=true, backup=true) click to toggle source
# File lib/git/stash/commit.rb, line 168
def tryStashCommitToInternal(stash, commitMessage, commit, reset=true, backup=true)
  root = BranchFactory::find stash.name.match(/^#{PREFIX}\/(.+)@.+$/)[1]

  $g.backup = createBackup root.name if backup

  case commit
  when Commit::ALL
    return false if !tryCommitAll(stash, commitMessage){stash.delete}
    root.checkout
  when Commit::PATCH
    return false if !tryCommitPatch(stash, commitMessage){stash.delete}

    if $g.patch
      $g.patch.rebaseOnto root.name, "#{$g.patch.name}~"

      if reset
        revision = Cmd::revision root.name
        root.rebase $g.patch.name
        $g.patch.delete
        root.reset revision
      else
        root.checkout
      end
    else
      root.checkout
    end
  end

  $g.backup.delete if backup

  return true
end
usage() click to toggle source

# File lib/git/stash/commit.rb, line 498
def usage
  print <<-EOS
usage)
  git stash-commit [--to (index | name)] [-m <commit message>] [-a | -p]
    options : --to              default: unused index
              -m | --message    default: "WIP on <branch>: <hash> <title>"
              -a | --all        default
              -p | --patch
    NOTE : --all   equal 'git commit --all'
           --patch equal 'git commit --patch'
  git stash-commit --from (index | name) [--no-reset]
    NOTE : --no-reset rebase only
  git stash-commit --continue
  git stash-commit --skip
  git stash-commit --abort
  git stash-commit --rename <oldname> <newname>
    NOTE : #{PREFIX}/<oldname>@to #{PREFIX}/<newname>@to
  git stash-commit -l [-a]
    options : -l | --list       listup stash-commit branch, in this group
              -a | --all        listup stash-commit branch all
  git stash-commit help
  git stash-commit <any args> [-d]
    options : -d | --debug      debug mode, show backtrace
EOS
end
validateFromTo(fromto) click to toggle source
# File lib/git/stash/commit.rb, line 32
def validateFromTo(fromto)
  # 数値 or ブランチ名
  if fromto == ''
    puts 'target name is empty'
    return false
  end
  if fromto.match(/^#{PREFIX}/)
    puts "/^#{PREFIX}/ is reserved words"
    return false
  end
  if fromto.match(/#{TMP_SUFFIX}$/)
    puts "/#{TMP_SUFFIX}$/ is reserved words"
    return false
  end
  if fromto.match(/#{PATCH_REMAIN_SUFFIX}$/)
    puts "/#{PATCH_REMAIN_SUFFIX}$/ is reserved words"
    return false
  end
  if fromto.match(/#{BACKUP_SUFFIX}$/)
    puts "/#{BACKUP_SUFFIX}$/ is reserved words"
    return false
  end
  if fromto.match(/@/)
    puts '@ is used in delimiter'
    return false
  end

  return true
end
validateRebase() click to toggle source

# File lib/git/stash/commit.rb, line 23
def validateRebase
  return true if $g.tmp
  return true if Cmd::rebaseInProgress?
  return true if $g.patch

  puts 'stash-commit (--continue | --skip | --abort) is not need'
  return false
end
validateRename(branch, renameOld, renameNew) click to toggle source
# File lib/git/stash/commit.rb, line 88
def validateRename(branch, renameOld, renameNew)
  return false if !validateStashCommitFromTo branch # 同じ
  return false if !validateFromTo renameOld
  return false if !validateFromTo renameNew
  if renameOld == renameNew
    puts "old:\"#{renameOld}\" new:\"#{renameNew}\" is same"
    return false
  end

  return true
end
validateStashCommitFrom(branch) click to toggle source
# File lib/git/stash/commit.rb, line 100
def validateStashCommitFrom(branch)
  if Cmd::changesCount != '0'
    puts 'find editing files, please fix it'
    return false
  end
  return false if !validateStashCommitFromTo branch

  return true
end
validateStashCommitFromTo(branch) click to toggle source
# File lib/git/stash/commit.rb, line 62
def validateStashCommitFromTo(branch)
  if Cmd::rebaseInProgress?
    puts 'now rebase in progress, please fix it'
    return false
  end
  if $g.tmp
    puts 'find tmp branch, please fix it'
    return false
  end
  if $g.patch
    puts 'find patch branch, please fix it'
    return false
  end
  if $g.backup
    puts'find backup branch, please fix it'
    return false
  end

  if branch.match(/^#{PREFIX}/)
    puts "can't work in stash-commit branch" # ネストはややこしい
    return false
  end

  return true
end
validateStashCommitTo(branch) click to toggle source
# File lib/git/stash/commit.rb, line 110
def validateStashCommitTo(branch)
  if Cmd::changesCount == '0'
    puts 'not need'
    return false
  end
  return false if !validateStashCommitFromTo branch

  return true
end
win?() click to toggle source
# File lib/git/stash/sclib/util.rb, line 21
def win?
  os == :windows
end