Сегодня на работе окончательно столкнулся (давно ждал) с проблемой, проистекающей из следующих моментов:
1. Есть большой веб-проект, куча файлов, все лежит на windows-шаре и хаотично модифицируется разными людьми
2. В процессе перехода к упорядоченной технологичной разработке ;) весь этот ужас затащен под SVN
3. На Linux’е НЕТ нормальных SVN-клиентов, кроме консольного, и, возможно, KDE-шного (не пробовал, ибо аллергия на Qt). Все остальные безумно тормозят и/или не осиливают. На венде я юзал TortoiseSVN, который с подобными задачами прекрасно справлялся.
Так вот, собственно, задача: закоммитить произвольное количество произвольных файлов в разных папках (но не все одновременно). Т.е., хочется их как-то по-простому выбирать.
Нет, можно, конечно, выводить список в файл, там редактировать, потом по нему прогонять commit, но долго, громоздко и лень.
Можно ручками составлять changelist, потом коммитить его – тоже тот ещё копипастинг.
Можно ставить галочки мышкой (a-la TortoiseSVN) с помощью всяких там NautilusSVN и т.п., но оно тормозит на таком количестве файлов (дома уже не помню, но МНОГО). Впрочем, как и остальные GUI-клиенты.
В общем, в процессе поиска решения наткнулся на Ruby-скрипт, который делает список измененных/удалённых/добавленных/неверсифицированных файлов, выдаёт его на редактирование, а потом коммитит. Почему мне не хватило мозгов написать самому – непонятно. Не привык мараться, видимо, да и просто ленивый. :( Но таки скрипт, на вид, вполне работоспособный, ломаться там нечему.
В общем, кому надо, вот:
#!/usr/bin/ruby
# A script that works in conjuction with Subversion. This script works by
# running svn status and finding all files which should be either added or
# committed. It then pops up SVN_EDITOR to allow modifying the list
# of files to commit. Once the editor is closed, this script calls svn commit
# without a message, allowing the user to create an appropriate message.
# If the list of files to commit includes files which have not yet been
# added to the repository, the script automagically adds them.
#
# Author: Francois Beausoleil (fbos_at_users.sourceforge.net)
# Date: 2003/08/23
require "tempfile"
SeparatorLine = "-- Move the files below above this point to add them automatically --"
files = []
unknown = []
open("|svn status", 'r') do |io|
io.each do |line|
files << $1 if line =~ /^[^?]\s+(.*)$/
unknown << $1 if line =~ /^\?\s+(.*)$/
raise "#{$1} has conflicts. Resolve the issue before committing" if
line =~ /^C\s+(.*)/
raise "#{$1} is missing. Run svn update to update your working copy" if
line =~ /^!\s+(.*)/
raise if line =~ /error/i
end
end
io = Tempfile.new("svn-commit.tmp")
files.each do |file|
io.print file, $/
end
io.print $/, SeparatorLine, $/, $/
unknown.each do |file|
io.print file, $/
end
io.close
raise "Unable to edit temporary file" unless
system("vim", io.path)
io.open
filestocommit = []
filestoadd = []
io.each do |line|
next if line =~ /^$/
break if line =~ /^#{SeparatorLine}$/
line.chomp!
filestoadd << line if unknown.include?(line)
filestocommit << line
end
io.close
if filestoadd.size > 0
raise "An error occured while adding files" unless
system "svn add #{filestoadd.join(' ')}"
end
if filestocommit.size > 0
raise "An error occured while committing the files" unless
system "svn commit #{filestocommit.join(' ')}"
end