2009-02-15 30 views
6

Tôi có tệp nhật ký được lưu trữ trong cơ sở dữ liệu SQLite mà tôi muốn phân phối trong kho lưu trữ git.Bảng SQLite với Git sáp nhập

Sau đó, tôi muốn các thay đổi đối với tệp nhật ký được hợp nhất tự động với tệp gốc.

Điều này có hoạt động không? Liệu một sự kết hợp nhị phân tự động vào một tệp SQLite có thổi lên thường xuyên hơn không?

+1

Nó có thực sự hợp nhất không? Nghĩa là, tệp sẽ thay đổi khác nhau trên hai nhánh riêng biệt? –

Trả lời

6

Tôi không tin rằng git thực sự là công cụ cho công việc của bạn. git là một công cụ quản lý mã nguồn phân tán, không phải là một công cụ sao chép cơ sở dữ liệu.

Việc hợp nhất tự động duy nhất mà git sẽ cố gắng là hợp nhất các tệp văn bản. Tệp nhật ký (thường là) tệp văn bản, vậy tại sao không đặt trực tiếp tệp này vào git và không phải vào cơ sở dữ liệu trước?

+0

Cảm ơn bạn đã đề xuất. –

5

Tôi nghi ngờ có bất kỳ hệ thống kiểm soát phiên bản chung nào (git, svn, cvs, v.v.) có thể xử lý cơ sở dữ liệu theo cách bạn mô tả. Nếu bạn nhấn mạnh vào việc sử dụng git để kết hợp cơ sở dữ liệu, tốt nhất là bạn nên chuyển đổi cơ sở dữ liệu thành tệp văn bản, hợp nhất tệp văn bản và tạo lại cơ sở dữ liệu. Ví dụ,

sqlite3 .dump > dump_file.txt 

có thể tạo ra tất cả các câu lệnh SQL cần thiết để làm lại cơ sở dữ liệu, sau đó bạn làm công cụ để các tập tin đổ, sau đó tạo ra một cơ sở dữ liệu SQLite với

sqlite3 newdatabase.db < modified_dump_file.txt 

Bạn sẽ có thể tự động hóa điều này bằng cách sử dụng một số loại git hook (tôi không quá quen thuộc với git).

1

Không có cách nào để hợp nhất các tệp nhị phân chính xác trong trường hợp này, vì vậy git không thể và sẽ không làm điều đó.

Với một số nỗ lực, bạn có thể sử dụng git cho các vùng cơ sở dữ liệu phiên bản, nhưng ngoại trừ trường hợp rất đơn giản bạn sẽ phải làm nhiều hơn là chỉ sử dụng các bãi thẳng. Bạn sẽ cần suy nghĩ về cách các hàng bị bán phá giá được sắp xếp dựa trên các cột chính của bạn, ít nhất là. Khác, bạn sẽ nhận được xung đột giả, hoặc hợp nhất tạo ra các bãi hợp lệ cú pháp đại diện cho một cơ sở dữ liệu rác.

F.ex., nếu các phiên bản khác nhau của một hàng có cùng khóa hiển thị trong các vùng dòng khác nhau của các phiên bản khác nhau của bãi chứa, git có thể nghĩ rằng nó hợp lý để giữ cho cả hai. Kết quả kết xuất sẽ có hai biểu diễn của cùng một hàng, đó là vô nghĩa.

Tóm lại, có thể bạn sẽ không hài lòng khi cố gắng giữ cơ sở dữ liệu được phiên bản bằng hệ thống kiểm soát nguồn.

17

Bạn cần xác định trình điều khiển hợp nhất và khác trong cấu hình git của mình, sau đó sử dụng các thuộc tính để liên kết chúng với các tệp.

Điều này chỉ thực hiện nhập văn bản đơn giản trên các bãi chứa, vì vậy nó có thể tạo ra tổng số vô nghĩa. Bạn hoàn toàn sẽ cần phải kiểm tra công việc của mình để chắc chắn rằng nó đã làm điều đúng Nó sẽ mất tedium ra khỏi sự hợp nhất dễ dàng mặc dù.

Trong .git bạn/config:

[merge "sqlite3"] 
    name = sqlite3 merge driver 
    driver = merge-sqlite3 %O %A %B 

[diff "sqlite3"] 
    name = sqlite3 diff driver 
    command = diff-sqlite3 

trong.gitattributes:

signons.sqlite diff=sqlite3 merge=sqlite3 

Và đâu đó trong đường dẫn của bạn, tên diff-sqlite3

#!/usr/bin/perl -w 

use File::Temp qw/ :POSIX /; 
use IPC::Run qw/run/ ; 

@ARGV == 7 or die sprintf 'wtf %s', join(' ', @ARGV); 

my ($name, $x, $y) = ($ARGV[0], $ARGV[1], $ARGV[4]); 

my ($a, $b); 

eval { 
    $a = tmpnam(); 
    $b = tmpnam(); 

    run ['sqlite3', $x, '.dump'], '>', $a or die 'sqlite3 failed'; 
    run ['sqlite3', $y, '.dump'], '>', $b or die 'sqlite3 failed'; 

    print "diff-sqlite3 a/$name b/$name\n"; 
    run ['diff', '-u', $a, $b, '--label', "a/$name", '--label', "b/$name"], '>', \*STDOUT; 

    unlink $a; 
    unlink $b; 
    1; 
} or do { 
    unlink $a if defined $a; 
    unlink $b if defined $b; 
    die [email protected]; 
} 

cũng trong đường dẫn của bạn, tên merge-sqlite3

#!/usr/bin/perl -w 

use File::Temp qw/ :POSIX /; 
use IPC::Run qw/run/ ; 

@ARGV == 3 or die sprintf 'wtf %s', join(' ', @ARGV); 

my ($o, $a, $b) = @ARGV; 

print "MERGEING SQLITE FILES $o $a $b\n"; 


eval { 
    $ad = tmpnam(); 
    $bd = tmpnam(); 
    $od = tmpnam(); 

    run ['sqlite3', $o, '.dump'], '>', $od or die 'sqlite3 failed'; 
    run ['sqlite3', $a, '.dump'], '>', $ad or die 'sqlite3 failed'; 
    run ['sqlite3', $b, '.dump'], '>', $bd or die 'sqlite3 failed'; 

    run ['merge', $ad, $od, $bd] or do { 
    my $newname = "$a.dump"; 
    my $n = 0; 
    while (-e $newname) { 
     ++$n; 
     $newname = "$a.dump.$n"; 
    } 
    print "merge failed, saving dump in $newname\n"; 
    rename $ad, $newname; 
    undef $ad; 
    die 'merge failed'; 
    }; 

    unlink $a or die $!; 
    my $err; 
    run ['sqlite3', $a], '>', \*STDOUT, '2>', \$err, '<', $ad; 
    if ('' ne $err) { 
    print STDERR $err; 
    die 'sqlite3 failed'; 
    } 

    unlink $ad if defined $ad; 
    unlink $bd; 
    unlink $od; 
    1; 
} or do { 
    unlink $ad if defined $ad; 
    unlink $bd if defined $bd; 
    unlink $od if defined $od; 

    die [email protected]; 
} 

Tôi chỉ hack những lên ngay bây giờ, bây giờ vì vậy bạn có thể phải ủi ra các kinks.

xem: http://git-scm.com/docs/gitattributeshttp://git-scm.com/docs/git-config

+0

Điều này thật tuyệt! Cảm ơn bạn, @smoofra! Rất hữu ích! – lindes

1

tôi reimplemented trình điều khiển khác trên trong shell script và thấy rằng nó không hoạt động đúng trong mọi trường hợp. Các kịch bản giả định hai tham số đầu tiên cung cấp cho các tập tin để diff, nhưng theo man git các thông số cho kịch bản là:

đường cũ-file cũ-hex cũ-mode mới-file mới hex mới chế độ

đây là diff rằng đã làm nó cho tôi:

#!/bin/sh 

FILE_PATH=$1 
OLD_FILE=$2 
OLD_HEX=$3 
OLD_MODE=$4 
NEW_FILE=$5 
NEW_HEX=$6 
NEW_MODE=$7 

A=`tempfile` 
B=`tempfile` 
test -f ${A} && test -f ${B} || exit 1 

sqlite3 ${OLD_FILE} .dump > ${A} && 
sqlite3 ${NEW_FILE} .dump > ${B} && 
diff -u ${A} ${B} --label "${FILE_PATH}@${OLD_HEX}" --label "${FILE_PATH}@${NEW_HEX}" 

rm ${A} 
rm ${B} 
2

Mặc dù câu hỏi này đã được hỏi 8 năm trước, tôi đã phát hành một công cụ thực hiện chính xác những gì bạn đang xin. Nó sử dụng một trình điều khiển khác tùy chỉnh tận dụng công cụ dự án sqlite 'sqldiff', UUID làm khóa chính, và rời khỏi hàng sqlite. Nó vẫn ở dạng alpha nên phản hồi được đánh giá cao.

https://github.com/cannadayr/git-sqlite

Các vấn đề liên quan