From 96775c62f71d795af1547f6ef92c2a8602fd32df Mon Sep 17 00:00:00 2001 From: Jasmin Lapalme Date: Mon, 19 Mar 2018 09:41:35 -0400 Subject: [PATCH] Add object-map option to get a map from the old sha1 to new sha1 #2766 --- commands/command_migrate.go | 10 ++++++++-- commands/command_migrate_import.go | 3 ++- git/githistory/rewriter.go | 20 ++++++++++++++++++++ test/test-migrate-import.sh | 17 +++++++++++++++++ 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/commands/command_migrate.go b/commands/command_migrate.go index 8aef8ab9..391524cd 100644 --- a/commands/command_migrate.go +++ b/commands/command_migrate.go @@ -32,6 +32,10 @@ var ( // migrateVerbose enables verbose logging migrateVerbose bool + + // objectMapFile is the path to the map of old sha1 to new sha1 + // commits + objectMapFilePath string ) // migrate takes the given command and arguments, *odb.ObjectDatabase, as well @@ -83,8 +87,9 @@ func rewriteOptions(args []string, opts *githistory.RewriteOptions, l *tasklog.L Include: include, Exclude: exclude, - UpdateRefs: opts.UpdateRefs, - Verbose: opts.Verbose, + UpdateRefs: opts.UpdateRefs, + Verbose: opts.Verbose, + ObjectMapFilePath: opts.ObjectMapFilePath, BlobFn: opts.BlobFn, TreeCallbackFn: opts.TreeCallbackFn, @@ -281,6 +286,7 @@ func init() { importCmd := NewCommand("import", migrateImportCommand) importCmd.Flags().BoolVar(&migrateVerbose, "verbose", false, "Verbose logging") + importCmd.Flags().StringVar(&objectMapFilePath, "object-map", "", "Object map file") RegisterCommand("migrate", nil, func(cmd *cobra.Command) { cmd.PersistentFlags().StringVarP(&includeArg, "include", "I", "", "Include a list of paths") diff --git a/commands/command_migrate_import.go b/commands/command_migrate_import.go index b9ac784b..0833f24b 100644 --- a/commands/command_migrate_import.go +++ b/commands/command_migrate_import.go @@ -36,7 +36,8 @@ func migrateImportCommand(cmd *cobra.Command, args []string) { gitfilter := lfs.NewGitFilter(cfg) migrate(args, rewriter, l, &githistory.RewriteOptions{ - Verbose: migrateVerbose, + Verbose: migrateVerbose, + ObjectMapFilePath: objectMapFilePath, BlobFn: func(path string, b *odb.Blob) (*odb.Blob, error) { if filepath.Base(path) == ".gitattributes" { return b, nil diff --git a/git/githistory/rewriter.go b/git/githistory/rewriter.go index 566e57e9..07f1d529 100644 --- a/git/githistory/rewriter.go +++ b/git/githistory/rewriter.go @@ -54,6 +54,10 @@ type RewriteOptions struct { // Verbose mode prints migrated objects. Verbose bool + // ObjectMapFilePath is the path to the map of old sha1 to new sha1 + // commits + ObjectMapFilePath string + // BlobFn specifies a function to rewrite blobs. // // It is called once per unique, unchanged path. That is to say, if @@ -188,6 +192,15 @@ func (r *Rewriter) Rewrite(opt *RewriteOptions) ([]byte, error) { vPerc = perc } + var objectMapFile *os.File + if len(opt.ObjectMapFilePath) > 0 { + objectMapFile, err = os.Create(opt.ObjectMapFilePath) + if err != nil { + return nil, fmt.Errorf("Could not create object map file: %v", err) + } + defer objectMapFile.Close() + } + // Keep track of the last commit that we rewrote. Callers often want // this so that they can perform a git-update-ref(1). var tip []byte @@ -253,6 +266,13 @@ func (r *Rewriter) Rewrite(opt *RewriteOptions) ([]byte, error) { if err != nil { return nil, err } + if len(opt.ObjectMapFilePath) > 0 { + mapStr := fmt.Sprintf("%s,%s\n", hex.EncodeToString(oid), hex.EncodeToString(newSha)) + _, err := objectMapFile.WriteString(mapStr) + if err != nil { + return nil, err + } + } } // Cache that commit so that we can reassign children of this diff --git a/test/test-migrate-import.sh b/test/test-migrate-import.sh index 1c1ff4ba..a2775bac 100755 --- a/test/test-migrate-import.sh +++ b/test/test-migrate-import.sh @@ -616,3 +616,20 @@ begin_test "migrate import (handle copies of files)" [ "$oid_root" = "$oid_root_after_migration" ] ) end_test + +begin_test "migrate import (--object-map)" +( + set -e + + setup_multiple_local_branches + + output_dir=$(mktemp -d) + + git log --all --pretty='format:%H' > "${output_dir}/old_sha.txt" + git lfs migrate import --everything --object-map "${output_dir}/object-map.txt" + git log --all --pretty='format:%H' > "${output_dir}/new_sha.txt" + paste -d',' "${output_dir}/old_sha.txt" "${output_dir}/new_sha.txt" > "${output_dir}/expected-map.txt" + + diff -u "${output_dir}/expected-map.txt" "${output_dir}/object-map.txt" +) +end_test