30
30
#include "date.h"
31
31
#include "commit.h"
32
32
#include "wildmatch.h"
33
+ #include "ident.h"
33
34
34
35
/*
35
36
* List of all available backends
@@ -2673,6 +2674,7 @@ struct migration_data {
2673
2674
struct ref_store * old_refs ;
2674
2675
struct ref_transaction * transaction ;
2675
2676
struct strbuf * errbuf ;
2677
+ struct strbuf sb ;
2676
2678
};
2677
2679
2678
2680
static int migrate_one_ref (const char * refname , const char * referent UNUSED , const struct object_id * oid ,
@@ -2705,6 +2707,52 @@ static int migrate_one_ref(const char *refname, const char *referent UNUSED, con
2705
2707
return ret ;
2706
2708
}
2707
2709
2710
+ struct reflog_migration_data {
2711
+ unsigned int index ;
2712
+ const char * refname ;
2713
+ struct ref_store * old_refs ;
2714
+ struct ref_transaction * transaction ;
2715
+ struct strbuf * errbuf ;
2716
+ struct strbuf * sb ;
2717
+ };
2718
+
2719
+ static int migrate_one_reflog_entry (struct object_id * old_oid ,
2720
+ struct object_id * new_oid ,
2721
+ const char * committer ,
2722
+ timestamp_t timestamp , int tz ,
2723
+ const char * msg , void * cb_data )
2724
+ {
2725
+ struct reflog_migration_data * data = cb_data ;
2726
+ const char * date ;
2727
+ int ret ;
2728
+
2729
+ date = show_date (timestamp , tz , DATE_MODE (NORMAL ));
2730
+ strbuf_reset (data -> sb );
2731
+ /* committer contains name and email */
2732
+ strbuf_addstr (data -> sb , fmt_ident ("" , committer , WANT_BLANK_IDENT , date , 0 ));
2733
+
2734
+ ret = ref_transaction_update_reflog (data -> transaction , data -> refname ,
2735
+ new_oid , old_oid , data -> sb -> buf ,
2736
+ REF_HAVE_NEW | REF_HAVE_OLD , msg ,
2737
+ data -> index ++ , data -> errbuf );
2738
+ return ret ;
2739
+ }
2740
+
2741
+ static int migrate_one_reflog (const char * refname , void * cb_data )
2742
+ {
2743
+ struct migration_data * migration_data = cb_data ;
2744
+ struct reflog_migration_data data = {
2745
+ .refname = refname ,
2746
+ .old_refs = migration_data -> old_refs ,
2747
+ .transaction = migration_data -> transaction ,
2748
+ .errbuf = migration_data -> errbuf ,
2749
+ .sb = & migration_data -> sb ,
2750
+ };
2751
+
2752
+ return refs_for_each_reflog_ent (migration_data -> old_refs , refname ,
2753
+ migrate_one_reflog_entry , & data );
2754
+ }
2755
+
2708
2756
static int move_files (const char * from_path , const char * to_path , struct strbuf * errbuf )
2709
2757
{
2710
2758
struct strbuf from_buf = STRBUF_INIT , to_buf = STRBUF_INIT ;
@@ -2771,13 +2819,6 @@ static int move_files(const char *from_path, const char *to_path, struct strbuf
2771
2819
return ret ;
2772
2820
}
2773
2821
2774
- static int count_reflogs (const char * reflog UNUSED , void * payload )
2775
- {
2776
- size_t * reflog_count = payload ;
2777
- (* reflog_count )++ ;
2778
- return 0 ;
2779
- }
2780
-
2781
2822
static int has_worktrees (void )
2782
2823
{
2783
2824
struct worktree * * worktrees = get_worktrees ();
@@ -2802,8 +2843,9 @@ int repo_migrate_ref_storage_format(struct repository *repo,
2802
2843
struct ref_store * old_refs = NULL , * new_refs = NULL ;
2803
2844
struct ref_transaction * transaction = NULL ;
2804
2845
struct strbuf new_gitdir = STRBUF_INIT ;
2805
- struct migration_data data ;
2806
- size_t reflog_count = 0 ;
2846
+ struct migration_data data = {
2847
+ .sb = STRBUF_INIT ,
2848
+ };
2807
2849
int did_migrate_refs = 0 ;
2808
2850
int ret ;
2809
2851
@@ -2815,21 +2857,6 @@ int repo_migrate_ref_storage_format(struct repository *repo,
2815
2857
2816
2858
old_refs = get_main_ref_store (repo );
2817
2859
2818
- /*
2819
- * We do not have any interfaces that would allow us to write many
2820
- * reflog entries. Once we have them we can remove this restriction.
2821
- */
2822
- if (refs_for_each_reflog (old_refs , count_reflogs , & reflog_count ) < 0 ) {
2823
- strbuf_addstr (errbuf , "cannot count reflogs" );
2824
- ret = -1 ;
2825
- goto done ;
2826
- }
2827
- if (reflog_count ) {
2828
- strbuf_addstr (errbuf , "migrating reflogs is not supported yet" );
2829
- ret = -1 ;
2830
- goto done ;
2831
- }
2832
-
2833
2860
/*
2834
2861
* Worktrees complicate the migration because every worktree has a
2835
2862
* separate ref storage. While it should be feasible to implement, this
@@ -2855,17 +2882,21 @@ int repo_migrate_ref_storage_format(struct repository *repo,
2855
2882
* This operation is safe as we do not yet modify the main
2856
2883
* repository.
2857
2884
*
2858
- * 3. If we're in dry-run mode then we are done and can hand over the
2885
+ * 3. Enumerate all reflogs and write them into the new ref storage.
2886
+ * This operation is safe as we do not yet modify the main
2887
+ * repository.
2888
+ *
2889
+ * 4. If we're in dry-run mode then we are done and can hand over the
2859
2890
* directory to the caller for inspection. If not, we now start
2860
2891
* with the destructive part.
2861
2892
*
2862
- * 4 . Delete the old ref storage from disk. As we have a copy of refs
2893
+ * 5 . Delete the old ref storage from disk. As we have a copy of refs
2863
2894
* in the new ref storage it's okay(ish) if we now get interrupted
2864
2895
* as there is an equivalent copy of all refs available.
2865
2896
*
2866
- * 5 . Move the new ref storage files into place.
2897
+ * 6 . Move the new ref storage files into place.
2867
2898
*
2868
- * 6 . Change the repository format to the new ref format.
2899
+ * 7 . Change the repository format to the new ref format.
2869
2900
*/
2870
2901
strbuf_addf (& new_gitdir , "%s/%s" , old_refs -> gitdir , "ref_migration.XXXXXX" );
2871
2902
if (!mkdtemp (new_gitdir .buf )) {
@@ -2907,6 +2938,10 @@ int repo_migrate_ref_storage_format(struct repository *repo,
2907
2938
if (ret < 0 )
2908
2939
goto done ;
2909
2940
2941
+ ret = refs_for_each_reflog (old_refs , migrate_one_reflog , & data );
2942
+ if (ret < 0 )
2943
+ goto done ;
2944
+
2910
2945
ret = ref_transaction_commit (transaction , errbuf );
2911
2946
if (ret < 0 )
2912
2947
goto done ;
@@ -2982,6 +3017,7 @@ int repo_migrate_ref_storage_format(struct repository *repo,
2982
3017
}
2983
3018
ref_transaction_free (transaction );
2984
3019
strbuf_release (& new_gitdir );
3020
+ strbuf_release (& data .sb );
2985
3021
return ret ;
2986
3022
}
2987
3023
0 commit comments