aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.junit
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.jgit.junit')
-rw-r--r--org.eclipse.jgit.junit/.classpath6
-rw-r--r--org.eclipse.jgit.junit/.settings/.api_filters11
-rw-r--r--org.eclipse.jgit.junit/.settings/org.eclipse.jdt.core.prefs169
-rw-r--r--org.eclipse.jgit.junit/.settings/org.eclipse.jdt.ui.prefs15
-rw-r--r--org.eclipse.jgit.junit/.settings/org.eclipse.mylyn.team.ui.prefs2
-rw-r--r--org.eclipse.jgit.junit/.settings/org.eclipse.pde.api.tools.prefs12
-rw-r--r--org.eclipse.jgit.junit/BUILD16
-rw-r--r--org.eclipse.jgit.junit/META-INF/MANIFEST.MF67
-rw-r--r--org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF8
-rw-r--r--org.eclipse.jgit.junit/OSGI-INF/l10n/plugin.properties2
-rw-r--r--org.eclipse.jgit.junit/build.properties4
-rw-r--r--org.eclipse.jgit.junit/plugin.properties2
-rw-r--r--org.eclipse.jgit.junit/pom.xml92
-rw-r--r--org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/Assert.java72
-rw-r--r--org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/FakeIndexFactory.java243
-rw-r--r--org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/JGitTestUtil.java216
-rw-r--r--org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java443
-rw-r--r--org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java212
-rw-r--r--org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/Repeat.java37
-rw-r--r--org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepeatRule.java139
-rw-r--r--org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java476
-rw-r--r--org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/SeparateClassloaderTestRunner.java69
-rw-r--r--org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/StrictWorkMonitor.java53
-rw-r--r--org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java637
-rw-r--r--org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRng.java53
-rw-r--r--org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/time/MonotonicFakeClock.java58
-rw-r--r--org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/time/TimeUtil.java68
27 files changed, 2413 insertions, 769 deletions
diff --git a/org.eclipse.jgit.junit/.classpath b/org.eclipse.jgit.junit/.classpath
index 098194ca4b..3628e33687 100644
--- a/org.eclipse.jgit.junit/.classpath
+++ b/org.eclipse.jgit.junit/.classpath
@@ -1,6 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17">
+ <attributes>
+ <attribute name="module" value="true"/>
+ </attributes>
+ </classpathentry>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
diff --git a/org.eclipse.jgit.junit/.settings/.api_filters b/org.eclipse.jgit.junit/.settings/.api_filters
new file mode 100644
index 0000000000..27815301c2
--- /dev/null
+++ b/org.eclipse.jgit.junit/.settings/.api_filters
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<component id="org.eclipse.jgit.junit" version="2">
+ <resource path="src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java" type="org.eclipse.jgit.junit.LocalDiskRepositoryTestCase">
+ <filter id="336658481">
+ <message_arguments>
+ <message_argument value="org.eclipse.jgit.junit.LocalDiskRepositoryTestCase"/>
+ <message_argument value="testRoot"/>
+ </message_arguments>
+ </filter>
+ </resource>
+</component>
diff --git a/org.eclipse.jgit.junit/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.junit/.settings/org.eclipse.jdt.core.prefs
index dcc0d3a0fe..c4412602ba 100644
--- a/org.eclipse.jgit.junit/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.junit/.settings/org.eclipse.jdt.core.prefs
@@ -1,19 +1,23 @@
eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=enabled
org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
-org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
-org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
-org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
-org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jgit.annotations.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnull.secondary=
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jgit.annotations.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary=
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jgit.annotations.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.compliance=17
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.problem.APILeak=warning
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.autoboxing=warning
@@ -24,8 +28,9 @@ org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=warning
org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
@@ -48,15 +53,15 @@ org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=error
-org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=error
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
-org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
@@ -64,41 +69,50 @@ org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning
org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
org.eclipse.jdt.core.compiler.problem.nullReference=error
org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=ignore
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=error
org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
-org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error
org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning
+org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled
+org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=info
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=error
+org.eclipse.jdt.core.compiler.problem.unstableAutoModuleName=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedImport=error
org.eclipse.jdt.core.compiler.problem.unusedLabel=error
org.eclipse.jdt.core.compiler.problem.unusedLocal=error
@@ -111,34 +125,66 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error
-org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=17
+org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=false
+org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns=false
+org.eclipse.jdt.core.formatter.align_with_spaces=false
+org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enum_constant=0
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field=49
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable=49
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method=49
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package=49
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter=0
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type=49
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assertion_message=0
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_loops=16
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain=0
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0
+org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16
org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_module_statements=16
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_record_components=16
+org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_shift_operator=0
+org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_type_annotations=0
+org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0
+org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0
org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration=0
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method=1
org.eclipse.jdt.core.formatter.blank_lines_before_field=1
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
@@ -147,6 +193,7 @@ org.eclipse.jdt.core.formatter.blank_lines_before_method=1
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch=0
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
@@ -156,12 +203,18 @@ org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_record_constructor=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_record_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped=false
+org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions=false
org.eclipse.jdt.core.formatter.comment.clear_blank_lines=false
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=false
org.eclipse.jdt.core.formatter.comment.format_block_comments=true
org.eclipse.jdt.core.formatter.comment.format_comments=true
org.eclipse.jdt.core.formatter.comment.format_header=false
@@ -171,7 +224,9 @@ org.eclipse.jdt.core.formatter.comment.format_line_comments=true
org.eclipse.jdt.core.formatter.comment.format_source_code=true
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.indent_tag_description=false
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags=do not insert
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
org.eclipse.jdt.core.formatter.comment.line_length=80
org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
@@ -183,10 +238,11 @@ org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
-org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=false
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_empty_lines=false
@@ -196,15 +252,17 @@ org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
org.eclipse.jdt.core.formatter.indentation.size=4
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
@@ -218,11 +276,15 @@ org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default=insert
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
@@ -248,10 +310,16 @@ org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arg
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_not_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
@@ -268,6 +336,7 @@ org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not ins
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
@@ -276,13 +345,20 @@ org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case=insert
+org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default=insert
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
@@ -299,6 +375,7 @@ org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not in
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
@@ -325,10 +402,15 @@ org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_ar
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
@@ -340,6 +422,8 @@ org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
@@ -355,6 +439,7 @@ org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
@@ -365,9 +450,12 @@ org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not inser
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
@@ -379,20 +467,63 @@ org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_decla
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.join_lines_in_comments=true
org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_code_block_on_one_line=one_line_never
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line=one_line_never
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_method_body_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line=false
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line=one_line_never
org.eclipse.jdt.core.formatter.lineSplit=80
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block=0
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block=0
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
org.eclipse.jdt.core.formatter.tabulation.char=tab
org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.text_block_indentation=0
org.eclipse.jdt.core.formatter.use_on_off_tags=true
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true
org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_before_relational_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_shift_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true
org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
diff --git a/org.eclipse.jgit.junit/.settings/org.eclipse.jdt.ui.prefs b/org.eclipse.jgit.junit/.settings/org.eclipse.jdt.ui.prefs
index c336cce6ed..5cfb8b6ac6 100644
--- a/org.eclipse.jgit.junit/.settings/org.eclipse.jdt.ui.prefs
+++ b/org.eclipse.jgit.junit/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,7 @@
eclipse.preferences.version=1
editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
formatter_profile=_JGit Format
-formatter_settings_version=12
+formatter_settings_version=21
org.eclipse.jdt.ui.ignorelowercasenames=true
org.eclipse.jdt.ui.importorder=java;javax;org;com;
org.eclipse.jdt.ui.ondemandthreshold=99
@@ -9,21 +9,23 @@ org.eclipse.jdt.ui.staticondemandthreshold=99
org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?><templates/>
sp_cleanup.add_default_serial_version_id=true
sp_cleanup.add_generated_serial_version_id=false
-sp_cleanup.add_missing_annotations=false
+sp_cleanup.add_missing_annotations=true
sp_cleanup.add_missing_deprecated_annotations=true
sp_cleanup.add_missing_methods=false
sp_cleanup.add_missing_nls_tags=false
sp_cleanup.add_missing_override_annotations=true
-sp_cleanup.add_missing_override_annotations_interface_methods=false
+sp_cleanup.add_missing_override_annotations_interface_methods=true
sp_cleanup.add_serial_version_id=false
sp_cleanup.always_use_blocks=true
sp_cleanup.always_use_parentheses_in_expressions=false
sp_cleanup.always_use_this_for_non_static_field_access=false
sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_functional_interfaces=false
sp_cleanup.convert_to_enhanced_for_loop=false
sp_cleanup.correct_indentation=false
sp_cleanup.format_source_code=true
sp_cleanup.format_source_code_changes_only=true
+sp_cleanup.insert_inferred_type_arguments=false
sp_cleanup.make_local_variable_final=false
sp_cleanup.make_parameters_final=false
sp_cleanup.make_private_fields_final=true
@@ -39,11 +41,12 @@ sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=
sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_type_arguments=true
sp_cleanup.remove_trailing_whitespaces=true
sp_cleanup.remove_trailing_whitespaces_all=true
sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
-sp_cleanup.remove_unnecessary_casts=false
-sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=true
sp_cleanup.remove_unused_imports=false
sp_cleanup.remove_unused_local_variables=false
sp_cleanup.remove_unused_private_fields=true
@@ -52,8 +55,10 @@ sp_cleanup.remove_unused_private_methods=true
sp_cleanup.remove_unused_private_types=true
sp_cleanup.sort_members=false
sp_cleanup.sort_members_all=false
+sp_cleanup.use_anonymous_class_creation=false
sp_cleanup.use_blocks=false
sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_lambda=false
sp_cleanup.use_parentheses_in_expressions=false
sp_cleanup.use_this_for_non_static_field_access=false
sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
diff --git a/org.eclipse.jgit.junit/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.jgit.junit/.settings/org.eclipse.mylyn.team.ui.prefs
index 0cba949fb7..2fca432276 100644
--- a/org.eclipse.jgit.junit/.settings/org.eclipse.mylyn.team.ui.prefs
+++ b/org.eclipse.jgit.junit/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -1,3 +1,3 @@
#Tue Jul 19 20:11:28 CEST 2011
-commit.comment.template=${task.description} \n\nBug\: ${task.key}
+commit.comment.template=${task.description}\n\nBug\: ${task.key}
eclipse.preferences.version=1
diff --git a/org.eclipse.jgit.junit/.settings/org.eclipse.pde.api.tools.prefs b/org.eclipse.jgit.junit/.settings/org.eclipse.pde.api.tools.prefs
index cd148d9049..c0030ded71 100644
--- a/org.eclipse.jgit.junit/.settings/org.eclipse.pde.api.tools.prefs
+++ b/org.eclipse.jgit.junit/.settings/org.eclipse.pde.api.tools.prefs
@@ -1,4 +1,4 @@
-#Tue Oct 18 00:52:01 CEST 2011
+ANNOTATION_ELEMENT_TYPE_ADDED_FIELD=Error
ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Error
ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Error
@@ -8,6 +8,10 @@ API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Error
API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Error
API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Error
API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Error
+API_USE_SCAN_FIELD_SEVERITY=Error
+API_USE_SCAN_METHOD_SEVERITY=Error
+API_USE_SCAN_TYPE_SEVERITY=Error
+CLASS_ELEMENT_TYPE_ADDED_FIELD=Error
CLASS_ELEMENT_TYPE_ADDED_METHOD=Error
CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
@@ -47,6 +51,7 @@ ILLEGAL_IMPLEMENT=Warning
ILLEGAL_INSTANTIATE=Warning
ILLEGAL_OVERRIDE=Warning
ILLEGAL_REFERENCE=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_DEFAULT_METHOD=Error
INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Error
INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Error
INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
@@ -58,6 +63,7 @@ INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Error
INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Error
INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+INVALID_ANNOTATION=Ignore
INVALID_JAVADOC_TAG=Ignore
INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Error
LEAK_EXTEND=Warning
@@ -75,6 +81,7 @@ METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error
METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+MISSING_EE_DESCRIPTIONS=Warning
TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error
TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error
TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error
@@ -83,10 +90,13 @@ TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error
TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error
UNUSED_PROBLEM_FILTERS=Warning
automatically_removed_unused_problem_filters=false
+changed_execution_env=Error
eclipse.preferences.version=1
incompatible_api_component_version=Error
incompatible_api_component_version_include_major_without_breaking_change=Disabled
incompatible_api_component_version_include_minor_without_api_change=Disabled
+incompatible_api_component_version_report_major_without_breaking_change=Warning
+incompatible_api_component_version_report_minor_without_api_change=Ignore
invalid_since_tag_version=Error
malformed_since_tag=Error
missing_since_tag=Error
diff --git a/org.eclipse.jgit.junit/BUILD b/org.eclipse.jgit.junit/BUILD
new file mode 100644
index 0000000000..f4a7165dbb
--- /dev/null
+++ b/org.eclipse.jgit.junit/BUILD
@@ -0,0 +1,16 @@
+load("@rules_java//java:defs.bzl", "java_library")
+
+package(default_visibility = ["//visibility:public"])
+
+java_library(
+ name = "junit",
+ testonly = 1,
+ srcs = glob(["src/**/*.java"]),
+ resource_strip_prefix = "org.eclipse.jgit.junit/resources",
+ resources = glob(["resources/**"], allow_empty=True),
+ deps = [
+ "//lib:junit",
+ # We want these deps to be provided_deps
+ "//org.eclipse.jgit:jgit",
+ ],
+)
diff --git a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
index 327a697f66..0ef8572bb5 100644
--- a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
@@ -1,25 +1,50 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
-Bundle-Name: %plugin_name
+Bundle-Name: %Bundle-Name
+Automatic-Module-Name: org.eclipse.jgit.junit
Bundle-SymbolicName: org.eclipse.jgit.junit
-Bundle-Version: 4.0.0.qualifier
-Bundle-Localization: plugin
-Bundle-Vendor: %provider_name
+Bundle-Version: 7.4.0.qualifier
+Bundle-Localization: OSGI-INF/l10n/plugin
+Bundle-Vendor: %Bundle-Vendor
Bundle-ActivationPolicy: lazy
-Bundle-RequiredExecutionEnvironment: JavaSE-1.7
-Import-Package: org.eclipse.jgit.api;version="[4.0.0,4.1.0)",
- org.eclipse.jgit.api.errors;version="[4.0.0,4.1.0)",
- org.eclipse.jgit.dircache;version="[4.0.0,4.1.0)",
- org.eclipse.jgit.errors;version="[4.0.0,4.1.0)",
- org.eclipse.jgit.internal.storage.file;version="[4.0.0,4.1.0)",
- org.eclipse.jgit.internal.storage.pack;version="[4.0.0,4.1.0)",
- org.eclipse.jgit.lib;version="[4.0.0,4.1.0)",
- org.eclipse.jgit.merge;version="[4.0.0,4.1.0)",
- org.eclipse.jgit.revwalk;version="[4.0.0,4.1.0)",
- org.eclipse.jgit.storage.file;version="[4.0.0,4.1.0)",
- org.eclipse.jgit.treewalk;version="[4.0.0,4.1.0)",
- org.eclipse.jgit.treewalk.filter;version="[4.0.0,4.1.0)",
- org.eclipse.jgit.util;version="[4.0.0,4.1.0)",
- org.eclipse.jgit.util.io;version="[4.0.0,4.1.0)",
- org.junit;version="[4.0.0,5.0.0)"
-Export-Package: org.eclipse.jgit.junit;version="4.0.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-17
+Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git
+Import-Package: org.eclipse.jgit.annotations;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.api;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.api.errors;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.dircache;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.errors;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.internal.storage.file;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.internal.util;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.lib;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.merge;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.revwalk;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.storage.file;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.storage.pack;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.transport;version="7.4.0",
+ org.eclipse.jgit.treewalk;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.treewalk.filter;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.util;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.util.io;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.util.time;version="[7.4.0,7.5.0)",
+ org.junit;version="[4.13,5.0.0)",
+ org.junit.rules;version="[4.13,5.0.0)",
+ org.junit.runner;version="[4.13,5.0.0)",
+ org.junit.runners;version="[4.13,5.0.0)",
+ org.junit.runners.model;version="[4.13,5.0.0)",
+ org.slf4j;version="[1.7.0,3.0.0)"
+Export-Package: org.eclipse.jgit.junit;version="7.4.0";
+ uses:="org.eclipse.jgit.dircache,
+ org.eclipse.jgit.lib,
+ org.eclipse.jgit.revwalk,
+ org.eclipse.jgit.internal.storage.file,
+ org.eclipse.jgit.treewalk,
+ org.eclipse.jgit.util,
+ org.eclipse.jgit.storage.file,
+ org.eclipse.jgit.api,
+ org.junit.rules,
+ org.junit.runners.model,
+ org.junit.runner,
+ org.eclipse.jgit.util.time",
+ org.eclipse.jgit.junit.time;version="7.4.0";uses:="org.eclipse.jgit.util.time"
diff --git a/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF
new file mode 100644
index 0000000000..dcd2abff21
--- /dev/null
+++ b/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF
@@ -0,0 +1,8 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: org.eclipse.jgit.junit - Sources
+Bundle-SymbolicName: org.eclipse.jgit.junit.source
+Bundle-Vendor: Eclipse.org - JGit
+Bundle-Version: 7.4.0.qualifier
+Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git
+Eclipse-SourceBundle: org.eclipse.jgit.junit;version="7.4.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit/OSGI-INF/l10n/plugin.properties b/org.eclipse.jgit.junit/OSGI-INF/l10n/plugin.properties
new file mode 100644
index 0000000000..f40f8e1d9f
--- /dev/null
+++ b/org.eclipse.jgit.junit/OSGI-INF/l10n/plugin.properties
@@ -0,0 +1,2 @@
+Bundle-Name=JGit JUnit Utility Classes
+Bundle-Vendor=Eclipse JGit
diff --git a/org.eclipse.jgit.junit/build.properties b/org.eclipse.jgit.junit/build.properties
index aa1a008269..931e1631af 100644
--- a/org.eclipse.jgit.junit/build.properties
+++ b/org.eclipse.jgit.junit/build.properties
@@ -1,5 +1,5 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
- .,\
- plugin.properties
+ OSGI-INF/,\
+ .
diff --git a/org.eclipse.jgit.junit/plugin.properties b/org.eclipse.jgit.junit/plugin.properties
deleted file mode 100644
index 9842967f52..0000000000
--- a/org.eclipse.jgit.junit/plugin.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-plugin_name=JGit JUnit Utility Classes
-provider_name=Eclipse JGit
diff --git a/org.eclipse.jgit.junit/pom.xml b/org.eclipse.jgit.junit/pom.xml
index 77f0511b34..f50b9d8aa2 100644
--- a/org.eclipse.jgit.junit/pom.xml
+++ b/org.eclipse.jgit.junit/pom.xml
@@ -1,47 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright (C) 2009, Google Inc.
- Copyright (C) 2008, Imran M Yousuf <imyousuf@smartitengineering.com>
- Copyright (C) 2010, Matthias Sohn <matthias.sohn@sap.com>
- and other copyright owners as documented in the project's IP log.
+ Copyright (C) 2009, Google Inc.
+ Copyright (C) 2008, Imran M Yousuf <imyousuf@smartitengineering.com>
+ Copyright (C) 2010, Matthias Sohn <matthias.sohn@sap.com> and others
- This program and the accompanying materials are made available
- under the terms of the Eclipse Distribution License v1.0 which
- accompanies this distribution, is reproduced below, and is
- available at http://www.eclipse.org/org/documents/edl-v10.php
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Distribution License v. 1.0 which is available at
+ http://www.eclipse.org/org/documents/edl-v10.php.
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or
- without modification, are permitted provided that the following
- conditions are met:
-
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- - Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
-
- - Neither the name of the Eclipse Foundation, Inc. nor the
- names of its contributors may be used to endorse or promote
- products derived from this software without specific prior
- written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ SPDX-License-Identifier: BSD-3-Clause
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
@@ -52,7 +19,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
- <version>4.0.0-SNAPSHOT</version>
+ <version>7.4.0-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit.junit</artifactId>
@@ -64,6 +31,7 @@
<properties>
<translate-qualifier/>
+ <source-bundle-manifest>${project.build.directory}/META-INF/SOURCE-MANIFEST.MF</source-bundle-manifest>
</properties>
<dependencies>
@@ -94,6 +62,48 @@
<plugins>
<plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>translate-source-qualifier</id>
+ <phase>generate-resources</phase>
+ <configuration>
+ <target>
+ <copy file="META-INF/SOURCE-MANIFEST.MF" tofile="${source-bundle-manifest}" overwrite="true"/>
+ <replace file="${source-bundle-manifest}">
+ <replacefilter token=".qualifier" value=".${commit.time.version}"/>
+ </replace>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <inherited>true</inherited>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <phase>process-classes</phase>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ <configuration>
+ <archive>
+ <manifestFile>${source-bundle-manifest}</manifestFile>
+ </archive>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/Assert.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/Assert.java
index 40a05b4b7c..6e0a8c79ab 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/Assert.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/Assert.java
@@ -1,58 +1,46 @@
/*
- * Copyright (C) 2012, Robin Rosenberg
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2012, Robin Rosenberg and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.junit;
-import static java.lang.Boolean.valueOf;
-
+/**
+ * Assertion class
+ */
public class Assert {
+ /**
+ * Assert booleans are equal
+ *
+ * @param expect
+ * expected value
+ * @param actual
+ * actual value
+ */
public static void assertEquals(boolean expect, boolean actual) {
- org.junit.Assert.assertEquals(valueOf(expect), valueOf(actual));
+ org.junit.Assert.assertEquals(Boolean.valueOf(expect),
+ Boolean.valueOf(actual));
}
+ /**
+ * Assert booleans are equal
+ *
+ * @param message
+ * message
+ * @param expect
+ * expected value
+ * @param actual
+ * actual value
+ */
public static void assertEquals(String message, boolean expect,
boolean actual) {
org.junit.Assert
- .assertEquals(message, valueOf(expect), valueOf(actual));
+ .assertEquals(message, Boolean.valueOf(expect),
+ Boolean.valueOf(actual));
}
}
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/FakeIndexFactory.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/FakeIndexFactory.java
new file mode 100644
index 0000000000..eb23bec584
--- /dev/null
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/FakeIndexFactory.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2025, Google Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.junit;
+
+import static java.util.function.Function.identity;
+import static java.util.stream.Collectors.toMap;
+import static java.util.stream.Collectors.toUnmodifiableList;
+
+import java.io.IOException;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jgit.errors.CorruptObjectException;
+import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.internal.storage.file.PackIndex;
+import org.eclipse.jgit.internal.storage.file.PackIndex.EntriesIterator;
+import org.eclipse.jgit.internal.storage.file.PackReverseIndex;
+import org.eclipse.jgit.lib.AbbreviatedObjectId;
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+
+/**
+ * Create indexes with predefined data
+ *
+ * @since 7.2
+ */
+public class FakeIndexFactory {
+
+ /**
+ * An object for the fake index
+ *
+ * @param name
+ * a sha1
+ * @param offset
+ * the (fake) position of the object in the pack
+ */
+ public record IndexObject(String name, long offset) {
+ /**
+ * Name (sha1) as an objectId
+ *
+ * @return name (a sha1) as an objectId.
+ */
+ public ObjectId getObjectId() {
+ return ObjectId.fromString(name);
+ }
+ }
+
+ /**
+ * Return an index populated with these objects
+ *
+ * @param objs
+ * objects to be indexed
+ * @return a PackIndex implementation
+ */
+ public static PackIndex indexOf(List<IndexObject> objs) {
+ return new FakePackIndex(objs);
+ }
+
+ /**
+ * Return a reverse pack index with these objects
+ *
+ * @param objs
+ * objects to be indexed
+ * @return a PackReverseIndex implementation
+ */
+ public static PackReverseIndex reverseIndexOf(List<IndexObject> objs) {
+ return new FakeReverseIndex(objs);
+ }
+
+ private FakeIndexFactory() {
+ }
+
+ private static class FakePackIndex implements PackIndex {
+ private static final Comparator<IndexObject> SHA1_COMPARATOR = (o1,
+ o2) -> String.CASE_INSENSITIVE_ORDER.compare(o1.name(),
+ o2.name());
+
+ private final Map<String, IndexObject> idx;
+
+ private final List<IndexObject> sha1Ordered;
+
+ private final long offset64count;
+
+ FakePackIndex(List<IndexObject> objs) {
+ sha1Ordered = objs.stream().sorted(SHA1_COMPARATOR)
+ .collect(toUnmodifiableList());
+ idx = objs.stream().collect(toMap(IndexObject::name, identity()));
+ offset64count = objs.stream()
+ .filter(o -> o.offset > Integer.MAX_VALUE).count();
+ }
+
+ @Override
+ public Iterator<MutableEntry> iterator() {
+ return new FakeEntriesIterator(sha1Ordered);
+ }
+
+ @Override
+ public long getObjectCount() {
+ return sha1Ordered.size();
+ }
+
+ @Override
+ public long getOffset64Count() {
+ return offset64count;
+ }
+
+ @Override
+ public ObjectId getObjectId(long nthPosition) {
+ return ObjectId
+ .fromString(sha1Ordered.get((int) nthPosition).name());
+ }
+
+ @Override
+ public long getOffset(long nthPosition) {
+ return sha1Ordered.get((int) nthPosition).offset();
+ }
+
+ @Override
+ public long findOffset(AnyObjectId objId) {
+ IndexObject o = idx.get(objId.name());
+ if (o == null) {
+ return -1;
+ }
+ return o.offset();
+ }
+
+ @Override
+ public int findPosition(AnyObjectId objId) {
+ IndexObject o = idx.get(objId.name());
+ if (o == null) {
+ return -1;
+ }
+ return sha1Ordered.indexOf(o);
+ }
+
+ @Override
+ public long findCRC32(AnyObjectId objId) throws MissingObjectException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean hasCRC32Support() {
+ return false;
+ }
+
+ @Override
+ public void resolve(Set<ObjectId> matches, AbbreviatedObjectId id,
+ int matchLimit) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public byte[] getChecksum() {
+ return new byte[0];
+ }
+ }
+
+ private static class FakeReverseIndex implements PackReverseIndex {
+ private static final Comparator<IndexObject> OFFSET_COMPARATOR = Comparator
+ .comparingLong(IndexObject::offset);
+
+ private final List<IndexObject> byOffset;
+
+ private final Map<Long, IndexObject> ridx;
+
+ FakeReverseIndex(List<IndexObject> objs) {
+ byOffset = objs.stream().sorted(OFFSET_COMPARATOR)
+ .collect(toUnmodifiableList());
+ ridx = byOffset.stream()
+ .collect(toMap(IndexObject::offset, identity()));
+ }
+
+ @Override
+ public void verifyPackChecksum(String packFilePath) {
+ // Do nothing
+ }
+
+ @Override
+ public ObjectId findObject(long offset) {
+ IndexObject indexObject = ridx.get(offset);
+ if (indexObject == null) {
+ return null;
+ }
+ return ObjectId.fromString(indexObject.name());
+ }
+
+ @Override
+ public long findNextOffset(long offset, long maxOffset)
+ throws CorruptObjectException {
+ IndexObject o = ridx.get(offset);
+ if (o == null) {
+ throw new CorruptObjectException("Invalid offset"); //$NON-NLS-1$
+ }
+ int pos = byOffset.indexOf(o);
+ if (pos == byOffset.size() - 1) {
+ return maxOffset;
+ }
+ return byOffset.get(pos + 1).offset();
+ }
+
+ @Override
+ public int findPosition(long offset) {
+ IndexObject indexObject = ridx.get(offset);
+ return byOffset.indexOf(indexObject);
+ }
+
+ @Override
+ public ObjectId findObjectByPosition(int nthPosition) {
+ return byOffset.get(nthPosition).getObjectId();
+ }
+ }
+
+ private static class FakeEntriesIterator extends EntriesIterator {
+
+ private static final byte[] buffer = new byte[Constants.OBJECT_ID_LENGTH];
+
+ private final Iterator<IndexObject> it;
+
+ FakeEntriesIterator(List<IndexObject> objs) {
+ super(objs.size());
+ it = objs.iterator();
+ }
+
+ @Override
+ protected void readNext() {
+ IndexObject next = it.next();
+ next.getObjectId().copyRawTo(buffer, 0);
+ setIdBuffer(buffer, 0);
+ setOffset(next.offset());
+ }
+ }
+}
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/JGitTestUtil.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/JGitTestUtil.java
index 136c64726f..177d8737cb 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/JGitTestUtil.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/JGitTestUtil.java
@@ -1,50 +1,19 @@
/*
* Copyright (C) 2008-2009, Google Inc.
* Copyright (C) 2008, Imran M Yousuf <imyousuf@smartitengineering.com>
- * Copyright (C) 2008, Jonas Fonseca <fonseca@diku.dk>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Jonas Fonseca <fonseca@diku.dk> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.junit;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
@@ -55,6 +24,7 @@ import java.io.Writer;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.net.URL;
+import java.nio.file.Path;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.util.FileUtils;
@@ -63,13 +33,22 @@ import org.eclipse.jgit.util.RawParseUtils;
import org.junit.Assert;
import org.junit.Test;
+/**
+ * Abstract test util class
+ */
public abstract class JGitTestUtil {
+ /** Constant <code>CLASSPATH_TO_RESOURCES="org/eclipse/jgit/test/resources/"</code> */
public static final String CLASSPATH_TO_RESOURCES = "org/eclipse/jgit/test/resources/";
private JGitTestUtil() {
throw new UnsupportedOperationException();
}
+ /**
+ * Get name of current test by inspecting stack trace
+ *
+ * @return the name
+ */
public static String getName() {
GatherStackTrace stack;
try {
@@ -108,6 +87,14 @@ public abstract class JGitTestUtil {
// Thrown above to collect the stack frame.
}
+ /**
+ * Assert byte arrays are equal
+ *
+ * @param exp
+ * expected value
+ * @param act
+ * actual value
+ */
public static void assertEquals(byte[] exp, byte[] act) {
Assert.assertEquals(s(exp), s(act));
}
@@ -116,7 +103,14 @@ public abstract class JGitTestUtil {
return RawParseUtils.decode(raw);
}
- public static File getTestResourceFile(final String fileName) {
+ /**
+ * Get test resource file.
+ *
+ * @param fileName
+ * file name
+ * @return the test resource file
+ */
+ public static File getTestResourceFile(String fileName) {
if (fileName == null || fileName.length() <= 0) {
return null;
}
@@ -144,23 +138,26 @@ public abstract class JGitTestUtil {
}
}
+ /**
+ * Copy test resource.
+ *
+ * @param name
+ * resource name
+ * @param dest
+ * destination file
+ * @throws IOException
+ * if an IO error occurred
+ */
public static void copyTestResource(String name, File dest)
throws IOException {
URL url = cl().getResource(CLASSPATH_TO_RESOURCES + name);
if (url == null)
throw new FileNotFoundException(name);
- InputStream in = url.openStream();
- try {
- FileOutputStream out = new FileOutputStream(dest);
- try {
- byte[] buf = new byte[4096];
- for (int n; (n = in.read(buf)) > 0;)
- out.write(buf, 0, n);
- } finally {
- out.close();
- }
- } finally {
- in.close();
+ try (InputStream in = url.openStream();
+ FileOutputStream out = new FileOutputStream(dest)) {
+ byte[] buf = new byte[4096];
+ for (int n; (n = in.read(buf)) > 0;)
+ out.write(buf, 0, n);
}
}
@@ -168,6 +165,19 @@ public abstract class JGitTestUtil {
return JGitTestUtil.class.getClassLoader();
}
+ /**
+ * Write a trash file.
+ *
+ * @param db
+ * the repository
+ * @param name
+ * file name
+ * @param data
+ * file content
+ * @return the trash file
+ * @throws IOException
+ * if an IO error occurred
+ */
public static File writeTrashFile(final Repository db,
final String name, final String data) throws IOException {
File path = new File(db.getWorkTree(), name);
@@ -175,6 +185,21 @@ public abstract class JGitTestUtil {
return path;
}
+ /**
+ * Write a trash file.
+ *
+ * @param db
+ * the repository
+ * @param subdir
+ * under working tree
+ * @param name
+ * file name
+ * @param data
+ * file content
+ * @return the trash file
+ * @throws IOException
+ * if an IO error occurred
+ */
public static File writeTrashFile(final Repository db,
final String subdir,
final String name, final String data) throws IOException {
@@ -197,14 +222,12 @@ public abstract class JGitTestUtil {
* @throws IOException
* the file could not be written.
*/
- public static void write(final File f, final String body)
+ public static void write(File f, String body)
throws IOException {
FileUtils.mkdirs(f.getParentFile(), true);
- Writer w = new OutputStreamWriter(new FileOutputStream(f), "UTF-8");
- try {
+ try (Writer w = new OutputStreamWriter(new FileOutputStream(f),
+ UTF_8)) {
w.write(body);
- } finally {
- w.close();
}
}
@@ -218,26 +241,99 @@ public abstract class JGitTestUtil {
* @throws IOException
* the file does not exist, or could not be read.
*/
- public static String read(final File file) throws IOException {
+ public static String read(File file) throws IOException {
final byte[] body = IO.readFully(file);
- return new String(body, 0, body.length, "UTF-8");
+ return new String(body, 0, body.length, UTF_8);
}
- public static String read(final Repository db, final String name)
+ /**
+ * Read a file's content
+ *
+ * @param db
+ * the repository
+ * @param name
+ * file name
+ * @return the content of the file
+ * @throws IOException
+ * if an IO error occurred
+ */
+ public static String read(Repository db, String name)
throws IOException {
File file = new File(db.getWorkTree(), name);
return read(file);
}
- public static boolean check(final Repository db, final String name) {
+ /**
+ * Check if file exists
+ *
+ * @param db
+ * the repository
+ * @param name
+ * name of the file
+ * @return {@code true} if the file exists
+ */
+ public static boolean check(Repository db, String name) {
File file = new File(db.getWorkTree(), name);
return file.exists();
}
+ /**
+ * Delete a trash file.
+ *
+ * @param db
+ * the repository
+ * @param name
+ * file name
+ * @throws IOException
+ * if an IO error occurred
+ */
public static void deleteTrashFile(final Repository db,
final String name) throws IOException {
File path = new File(db.getWorkTree(), name);
FileUtils.delete(path);
}
+ /**
+ * Write a symbolic link
+ *
+ * @param db
+ * the repository
+ * @param link
+ * the path of the symbolic link to create
+ * @param target
+ * the target of the symbolic link
+ * @return the path to the symbolic link
+ * @throws Exception
+ * if an error occurred
+ * @since 4.2
+ */
+ public static Path writeLink(Repository db, String link,
+ String target) throws Exception {
+ return FileUtils.createSymLink(new File(db.getWorkTree(), link),
+ target);
+ }
+
+ /**
+ * Concatenate byte arrays.
+ *
+ * @param b
+ * byte arrays to combine together.
+ * @return a single byte array that contains all bytes copied from input
+ * byte arrays.
+ * @since 4.9
+ */
+ public static byte[] concat(byte[]... b) {
+ int n = 0;
+ for (byte[] a : b) {
+ n += a.length;
+ }
+
+ byte[] data = new byte[n];
+ n = 0;
+ for (byte[] a : b) {
+ System.arraycopy(a, 0, data, n, a.length);
+ n += a.length;
+ }
+ return data;
+ }
}
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java
index b98db7d187..0d20f6488a 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java
@@ -1,64 +1,41 @@
/*
* Copyright (C) 2009-2010, Google Inc.
* Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2007, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2007, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.junit;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.IOException;
-import java.util.ArrayList;
+import java.io.PrintStream;
+import java.time.Instant;
+import java.time.ZoneId;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.TimeUnit;
+import java.util.Random;
+import java.util.Set;
+import java.util.TreeSet;
+import org.eclipse.jgit.dircache.DirCache;
+import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryCache;
@@ -69,6 +46,9 @@ import org.eclipse.jgit.util.FileUtils;
import org.eclipse.jgit.util.SystemReader;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
/**
* JUnit TestCase with specialized support for temporary local repository.
@@ -76,8 +56,9 @@ import org.junit.Before;
* A temporary directory is created for each test, allowing each test to use a
* fresh environment. The temporary directory is cleaned up after the test ends.
* <p>
- * Callers should not use {@link RepositoryCache} from within these tests as it
- * may wedge file descriptors open past the end of the test.
+ * Callers should not use {@link org.eclipse.jgit.lib.RepositoryCache} from
+ * within these tests as it may wedge file descriptors open past the end of the
+ * test.
* <p>
* A system property {@code jgit.junit.usemmap} defines whether memory mapping
* is used. Memory mapping has an effect on the file system, in that memory
@@ -97,31 +78,92 @@ public abstract class LocalDiskRepositoryTestCase {
/** A fake (but stable) identity for committer fields in the test. */
protected PersonIdent committer;
- private final List<Repository> toClose = new ArrayList<Repository>();
+ /**
+ * A {@link SystemReader} used to coordinate time, envars, etc.
+ * @since 4.2
+ */
+ protected MockSystemReader mockSystemReader;
+
+ private final Set<Repository> toClose = new HashSet<>();
+
+ /**
+ * Temporary test root directory for files created by tests.
+ * @since 7.2
+ */
+ @Rule
+ public TemporaryFolder testRoot = new TemporaryFolder();
+
+ Random rand = new Random();
+
private File tmp;
- private MockSystemReader mockSystemReader;
+ private File homeDir;
+ /**
+ * The current test name.
+ *
+ * @since 6.0.1
+ */
+ @Rule
+ public TestName currentTest = new TestName();
+
+ private String getTestName() {
+ String name = currentTest.getMethodName();
+ name = name.replaceAll("[^a-zA-Z0-9]", "_");
+ name = name.replaceAll("__+", "_");
+ if (name.startsWith("_")) {
+ name = name.substring(1);
+ }
+ return name;
+ }
+
+ /**
+ * Setup test
+ *
+ * @throws Exception
+ * if an error occurred
+ */
@Before
public void setUp() throws Exception {
- tmp = File.createTempFile("jgit_test_", "_tmp");
- CleanupThread.deleteOnShutdown(tmp);
- if (!tmp.delete() || !tmp.mkdir())
- throw new IOException("Cannot create " + tmp);
+ tmp = testRoot.newFolder(getTestName() + rand.nextInt());
mockSystemReader = new MockSystemReader();
- mockSystemReader.userGitConfig = new FileBasedConfig(new File(tmp,
- "usergitconfig"), FS.DETECTED);
- ceilTestDirectories(getCeilings());
SystemReader.setInstance(mockSystemReader);
- final long now = mockSystemReader.getCurrentTime();
- final int tz = mockSystemReader.getTimezone(now);
- author = new PersonIdent("J. Author", "jauthor@example.com");
- author = new PersonIdent(author, now, tz);
+ // Mock the home directory. We don't want to pick up the real user's git
+ // config, or global git ignore.
+ // XDG_CONFIG_HOME isn't set in the MockSystemReader.
+ mockSystemReader.setProperty("user.home", tmp.getAbsolutePath());
+ mockSystemReader.setProperty("HOME", tmp.getAbsolutePath());
+ homeDir = FS.DETECTED.userHome();
+ FS.DETECTED.setUserHome(tmp.getAbsoluteFile());
+
+ // Measure timer resolution before the test to avoid time critical tests
+ // are affected by time needed for measurement.
+ // The MockSystemReader must be configured first since we need to use
+ // the same one here
+ FS.getFileStoreAttributes(tmp.toPath().getParent());
+
+ FileBasedConfig jgitConfig = new FileBasedConfig(
+ new File(tmp, "jgitconfig"), FS.DETECTED);
+ FileBasedConfig systemConfig = new FileBasedConfig(jgitConfig,
+ new File(tmp, "systemgitconfig"), FS.DETECTED);
+ FileBasedConfig userConfig = new FileBasedConfig(systemConfig,
+ new File(tmp, "usergitconfig"), FS.DETECTED);
+ // We have to set autoDetach to false for tests, because tests expect to be able
+ // to clean up by recursively removing the repository, and background GC might be
+ // in the middle of writing or deleting files, which would disrupt this.
+ userConfig.setBoolean(ConfigConstants.CONFIG_GC_SECTION,
+ null, ConfigConstants.CONFIG_KEY_AUTODETACH, false);
+ userConfig.save();
+ mockSystemReader.setJGitConfig(jgitConfig);
+ mockSystemReader.setSystemGitConfig(systemConfig);
+ mockSystemReader.setUserGitConfig(userConfig);
+
+ ceilTestDirectories(getCeilings());
+ author = new PersonIdent("J. Author", "jauthor@example.com");
committer = new PersonIdent("J. Committer", "jcommitter@example.com");
- committer = new PersonIdent(committer, now, tz);
final WindowCacheConfig c = new WindowCacheConfig();
c.setPackedGitLimit(128 * WindowCacheConfig.KB);
@@ -131,10 +173,20 @@ public abstract class LocalDiskRepositoryTestCase {
c.install();
}
+ /**
+ * Get temporary directory.
+ *
+ * @return the temporary directory
+ */
protected File getTemporaryDirectory() {
return tmp.getAbsoluteFile();
}
+ /**
+ * Get list of ceiling directories
+ *
+ * @return list of ceiling directories
+ */
protected List<File> getCeilings() {
return Collections.singletonList(getTemporaryDirectory());
}
@@ -153,33 +205,38 @@ public abstract class LocalDiskRepositoryTestCase {
return stringBuilder.toString();
}
+ /**
+ * Tear down the test
+ *
+ * @throws Exception
+ * if an error occurred
+ */
@After
public void tearDown() throws Exception {
RepositoryCache.clear();
- for (Repository r : toClose)
+ for (Repository r : toClose) {
r.close();
+ }
toClose.clear();
// Since memory mapping is controlled by the GC we need to
// tell it this is a good time to clean up and unlock
// memory mapped files.
//
- if (useMMAP)
+ if (useMMAP) {
System.gc();
- if (tmp != null)
- recursiveDelete(tmp, false, true);
- if (tmp != null && !tmp.exists())
- CleanupThread.removed(tmp);
-
+ }
+ FS.DETECTED.setUserHome(homeDir);
SystemReader.setInstance(null);
}
- /** Increment the {@link #author} and {@link #committer} times. */
+ /**
+ * Increment the {@link #author} and {@link #committer} times.
+ */
protected void tick() {
- final long delta = TimeUnit.MILLISECONDS.convert(5 * 60,
- TimeUnit.SECONDS);
- final long now = author.getWhen().getTime() + delta;
- final int tz = mockSystemReader.getTimezone(now);
+ mockSystemReader.tick(5 * 60);
+ Instant now = mockSystemReader.now();
+ ZoneId tz = mockSystemReader.getTimeZoneId();
author = new PersonIdent(author, now, tz);
committer = new PersonIdent(committer, now, tz);
@@ -191,48 +248,147 @@ public abstract class LocalDiskRepositoryTestCase {
* @param dir
* the recursively directory to delete, if present.
*/
- protected void recursiveDelete(final File dir) {
+ protected void recursiveDelete(File dir) {
recursiveDelete(dir, false, true);
}
private static boolean recursiveDelete(final File dir,
boolean silent, boolean failOnError) {
assert !(silent && failOnError);
- if (!dir.exists())
- return silent;
- final File[] ls = dir.listFiles();
- if (ls != null)
- for (int k = 0; k < ls.length; k++) {
- final File e = ls[k];
- if (e.isDirectory())
- silent = recursiveDelete(e, silent, failOnError);
- else if (!e.delete()) {
- if (!silent)
- reportDeleteFailure(failOnError, e);
- silent = !failOnError;
- }
- }
- if (!dir.delete()) {
- if (!silent)
- reportDeleteFailure(failOnError, dir);
- silent = !failOnError;
+ int options = FileUtils.RECURSIVE | FileUtils.RETRY
+ | FileUtils.SKIP_MISSING;
+ if (silent) {
+ options |= FileUtils.IGNORE_ERRORS;
}
- return silent;
+ try {
+ FileUtils.delete(dir, options);
+ } catch (IOException e) {
+ reportDeleteFailure(failOnError, dir, e);
+ return !failOnError;
+ }
+ return true;
}
- private static void reportDeleteFailure(boolean failOnError, File e) {
+ private static void reportDeleteFailure(boolean failOnError, File f,
+ Exception cause) {
String severity = failOnError ? "ERROR" : "WARNING";
- String msg = severity + ": Failed to delete " + e;
- if (failOnError)
+ String msg = severity + ": Failed to delete " + f;
+ if (failOnError) {
fail(msg);
- else
+ } else {
System.err.println(msg);
+ }
+ cause.printStackTrace(new PrintStream(System.err));
+ }
+
+ /** Constant <code>MOD_TIME=1</code> */
+ public static final int MOD_TIME = 1;
+
+ /** Constant <code>SMUDGE=2</code> */
+ public static final int SMUDGE = 2;
+
+ /** Constant <code>LENGTH=4</code> */
+ public static final int LENGTH = 4;
+
+ /** Constant <code>CONTENT_ID=8</code> */
+ public static final int CONTENT_ID = 8;
+
+ /** Constant <code>CONTENT=16</code> */
+ public static final int CONTENT = 16;
+
+ /** Constant <code>ASSUME_UNCHANGED=32</code> */
+ public static final int ASSUME_UNCHANGED = 32;
+
+ /**
+ * Represent the state of the index in one String. This representation is
+ * useful when writing tests which do assertions on the state of the index.
+ * By default information about path, mode, stage (if different from 0) is
+ * included. A bitmask controls which additional info about
+ * modificationTimes, smudge state and length is included.
+ * <p>
+ * The format of the returned string is described with this BNF:
+ *
+ * <pre>
+ * result = ( "[" path mode stage? time? smudge? length? sha1? content? "]" )* .
+ * mode = ", mode:" number .
+ * stage = ", stage:" number .
+ * time = ", time:t" timestamp-index .
+ * smudge = "" | ", smudged" .
+ * length = ", length:" number .
+ * sha1 = ", sha1:" hex-sha1 .
+ * content = ", content:" blob-data .
+ * </pre>
+ *
+ * 'stage' is only presented when the stage is different from 0. All
+ * reported time stamps are mapped to strings like "t0", "t1", ... "tn". The
+ * smallest reported time-stamp will be called "t0". This allows to write
+ * assertions against the string although the concrete value of the time
+ * stamps is unknown.
+ *
+ * @param repo
+ * the repository the index state should be determined for
+ * @param includedOptions
+ * a bitmask constructed out of the constants {@link #MOD_TIME},
+ * {@link #SMUDGE}, {@link #LENGTH}, {@link #CONTENT_ID} and
+ * {@link #CONTENT} controlling which info is present in the
+ * resulting string.
+ * @return a string encoding the index state
+ * @throws IOException
+ * if an IO error occurred
+ */
+ public static String indexState(Repository repo, int includedOptions)
+ throws IOException {
+ DirCache dc = repo.readDirCache();
+ StringBuilder sb = new StringBuilder();
+ TreeSet<Instant> timeStamps = new TreeSet<>();
+
+ // iterate once over the dircache just to collect all time stamps
+ if (0 != (includedOptions & MOD_TIME)) {
+ for (int i = 0; i < dc.getEntryCount(); ++i) {
+ timeStamps.add(dc.getEntry(i).getLastModifiedInstant());
+ }
+ }
+
+ // iterate again, now produce the result string
+ for (int i=0; i<dc.getEntryCount(); ++i) {
+ DirCacheEntry entry = dc.getEntry(i);
+ sb.append("["+entry.getPathString()+", mode:" + entry.getFileMode());
+ int stage = entry.getStage();
+ if (stage != 0)
+ sb.append(", stage:" + stage);
+ if (0 != (includedOptions & MOD_TIME)) {
+ sb.append(", time:t"+
+ timeStamps.headSet(entry.getLastModifiedInstant())
+ .size());
+ }
+ if (0 != (includedOptions & SMUDGE))
+ if (entry.isSmudged())
+ sb.append(", smudged");
+ if (0 != (includedOptions & LENGTH))
+ sb.append(", length:"
+ + Integer.toString(entry.getLength()));
+ if (0 != (includedOptions & CONTENT_ID))
+ sb.append(", sha1:" + ObjectId.toString(entry.getObjectId()));
+ if (0 != (includedOptions & CONTENT)) {
+ sb.append(", content:"
+ + new String(repo.open(entry.getObjectId(),
+ Constants.OBJ_BLOB).getCachedBytes(), UTF_8));
+ }
+ if (0 != (includedOptions & ASSUME_UNCHANGED))
+ sb.append(", assume-unchanged:"
+ + Boolean.toString(entry.isAssumeValid()));
+ sb.append("]");
+ }
+ return sb.toString();
}
+
/**
* Creates a new empty bare repository.
*
- * @return the newly created repository, opened for access
+ * @return the newly created bare repository, opened for access. The
+ * repository will not be closed in {@link #tearDown()}; the caller
+ * is responsible for closing it.
* @throws IOException
* the repository could not be created in the temporary area
*/
@@ -243,7 +399,9 @@ public abstract class LocalDiskRepositoryTestCase {
/**
* Creates a new empty repository within a new empty working directory.
*
- * @return the newly created repository, opened for access
+ * @return the newly created repository, opened for access. The repository
+ * will not be closed in {@link #tearDown()}; the caller is
+ * responsible for closing it.
* @throws IOException
* the repository could not be created in the temporary area
*/
@@ -257,16 +415,41 @@ public abstract class LocalDiskRepositoryTestCase {
* @param bare
* true to create a bare repository; false to make a repository
* within its working directory
+ * @return the newly created repository, opened for access. The repository
+ * will not be closed in {@link #tearDown()}; the caller is
+ * responsible for closing it.
+ * @throws IOException
+ * the repository could not be created in the temporary area
+ * @since 5.3
+ */
+ protected FileRepository createRepository(boolean bare)
+ throws IOException {
+ return createRepository(bare, false /* auto close */);
+ }
+
+ /**
+ * Creates a new empty repository.
+ *
+ * @param bare
+ * true to create a bare repository; false to make a repository
+ * within its working directory
+ * @param autoClose
+ * auto close the repository in {@link #tearDown()}
* @return the newly created repository, opened for access
* @throws IOException
* the repository could not be created in the temporary area
+ * @deprecated use {@link #createRepository(boolean)} instead
*/
- private FileRepository createRepository(boolean bare) throws IOException {
+ @Deprecated
+ public FileRepository createRepository(boolean bare, boolean autoClose)
+ throws IOException {
File gitdir = createUniqueTestGitDir(bare);
FileRepository db = new FileRepository(gitdir);
assertFalse(gitdir.exists());
db.create(bare);
- toClose.add(db);
+ if (autoClose) {
+ addRepoToClose(db);
+ }
return db;
}
@@ -288,6 +471,7 @@ public abstract class LocalDiskRepositoryTestCase {
* a subdirectory
* @return a unique directory for a test
* @throws IOException
+ * if an IO error occurred
*/
protected File createTempDirectory(String name) throws IOException {
File directory = new File(createTempFile(), name);
@@ -303,6 +487,7 @@ public abstract class LocalDiskRepositoryTestCase {
* working directory
* @return a unique directory for a test repository
* @throws IOException
+ * if an IO error occurred
*/
protected File createUniqueTestGitDir(boolean bare) throws IOException {
String gitdirName = createTempFile().getPath();
@@ -323,6 +508,7 @@ public abstract class LocalDiskRepositoryTestCase {
*
* @return a unique path that does not exist.
* @throws IOException
+ * if an IO error occurred
*/
protected File createTempFile() throws IOException {
File p = File.createTempFile("tmp_", "", tmp);
@@ -386,18 +572,12 @@ public abstract class LocalDiskRepositoryTestCase {
* @throws IOException
* the file could not be written.
*/
- protected File write(final String body) throws IOException {
+ protected File write(String body) throws IOException {
final File f = File.createTempFile("temp", "txt", tmp);
try {
write(f, body);
return f;
- } catch (Error e) {
- f.delete();
- throw e;
- } catch (RuntimeException e) {
- f.delete();
- throw e;
- } catch (IOException e) {
+ } catch (Error | RuntimeException | IOException e) {
f.delete();
throw e;
}
@@ -417,15 +597,24 @@ public abstract class LocalDiskRepositoryTestCase {
* @throws IOException
* the file could not be written.
*/
- protected void write(final File f, final String body) throws IOException {
+ protected void write(File f, String body) throws IOException {
JGitTestUtil.write(f, body);
}
- protected String read(final File f) throws IOException {
+ /**
+ * Read a file's content
+ *
+ * @param f
+ * the file
+ * @return the content of the file
+ * @throws IOException
+ * if an IO error occurred
+ */
+ protected String read(File f) throws IOException {
return JGitTestUtil.read(f);
}
- private static String[] toEnvArray(final Map<String, String> env) {
+ private static String[] toEnvArray(Map<String, String> env) {
final String[] envp = new String[env.size()];
int i = 0;
for (Map.Entry<String, String> e : env.entrySet())
@@ -434,44 +623,6 @@ public abstract class LocalDiskRepositoryTestCase {
}
private static HashMap<String, String> cloneEnv() {
- return new HashMap<String, String>(System.getenv());
- }
-
- private static final class CleanupThread extends Thread {
- private static final CleanupThread me;
- static {
- me = new CleanupThread();
- Runtime.getRuntime().addShutdownHook(me);
- }
-
- static void deleteOnShutdown(File tmp) {
- synchronized (me) {
- me.toDelete.add(tmp);
- }
- }
-
- static void removed(File tmp) {
- synchronized (me) {
- me.toDelete.remove(tmp);
- }
- }
-
- private final List<File> toDelete = new ArrayList<File>();
-
- @Override
- public void run() {
- // On windows accidentally open files or memory
- // mapped regions may prevent files from being deleted.
- // Suggesting a GC increases the likelihood that our
- // test repositories actually get removed after the
- // tests, even in the case of failure.
- System.gc();
- synchronized (this) {
- boolean silent = false;
- boolean failOnError = false;
- for (File tmp : toDelete)
- recursiveDelete(tmp, silent, failOnError);
- }
- }
+ return new HashMap<>(System.getenv());
}
}
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java
index 65551d6579..38f0d0b2cb 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java
@@ -1,68 +1,46 @@
/*
* Copyright (C) 2009, Google Inc.
* Copyright (C) 2009, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2009, Yann Simon <yann.simon.fr@gmail.com>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2009, Yann Simon <yann.simon.fr@gmail.com> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.junit;
import java.io.File;
import java.io.IOException;
+import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
+import java.time.Duration;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
+import java.util.concurrent.TimeUnit;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.SystemReader;
+import org.eclipse.jgit.util.time.MonotonicClock;
+import org.eclipse.jgit.util.time.ProposedTimestamp;
+/**
+ * Mock {@link org.eclipse.jgit.util.SystemReader} for tests.
+ */
public class MockSystemReader extends SystemReader {
- private final class MockConfig extends FileBasedConfig {
+ private static final class MockConfig extends FileBasedConfig {
private MockConfig(File cfgLocation, FS fs) {
super(cfgLocation, fs);
}
@@ -73,17 +51,73 @@ public class MockSystemReader extends SystemReader {
}
@Override
+ public void save() throws IOException {
+ // Do nothing
+ }
+
+ @Override
public boolean isOutdated() {
return false;
}
+
+ @Override
+ public String toString() {
+ return "MockConfig";
+ }
}
- final Map<String, String> values = new HashMap<String, String>();
+ long now = 1250379778668L; // Sat Aug 15 20:12:58 GMT-03:30 2009
- FileBasedConfig userGitConfig;
+ final Map<String, String> values = new HashMap<>();
+
+ private FileBasedConfig userGitConfig;
+
+ private FileBasedConfig jgitConfig;
FileBasedConfig systemGitConfig;
+ /**
+ * Set the user-level git config
+ *
+ * @param userGitConfig
+ * set another user-level git config
+ * @return the old user-level git config
+ * @since 5.1.9
+ */
+ public FileBasedConfig setUserGitConfig(FileBasedConfig userGitConfig) {
+ FileBasedConfig old = this.userGitConfig;
+ this.userGitConfig = userGitConfig;
+ return old;
+ }
+
+ /**
+ * Set the jgit config stored at $XDG_CONFIG_HOME/jgit/config
+ *
+ * @param jgitConfig
+ * set the jgit configuration
+ * @since 5.5
+ */
+ public void setJGitConfig(FileBasedConfig jgitConfig) {
+ this.jgitConfig = jgitConfig;
+ }
+
+ /**
+ * Set the system-level git config
+ *
+ * @param systemGitConfig
+ * the new system-level git config
+ * @return the old system-level config
+ * @since 5.1.9
+ */
+ public FileBasedConfig setSystemGitConfig(FileBasedConfig systemGitConfig) {
+ FileBasedConfig old = this.systemGitConfig;
+ this.systemGitConfig = systemGitConfig;
+ return old;
+ }
+
+ /**
+ * Constructor for <code>MockSystemReader</code>
+ */
public MockSystemReader() {
init(Constants.OS_USER_NAME_KEY);
init(Constants.GIT_AUTHOR_NAME_KEY);
@@ -92,18 +126,30 @@ public class MockSystemReader extends SystemReader {
init(Constants.GIT_COMMITTER_EMAIL_KEY);
setProperty(Constants.OS_USER_DIR, ".");
userGitConfig = new MockConfig(null, null);
+ jgitConfig = new MockConfig(null, null);
systemGitConfig = new MockConfig(null, null);
setCurrentPlatform();
}
- private void init(final String n) {
+ private void init(String n) {
setProperty(n, n);
}
+ /**
+ * Clear properties
+ */
public void clearProperties() {
values.clear();
}
+ /**
+ * Set a property
+ *
+ * @param key
+ * the key
+ * @param value
+ * the value
+ */
public void setProperty(String key, String value) {
values.put(key, value);
}
@@ -131,13 +177,60 @@ public class MockSystemReader extends SystemReader {
}
@Override
+ public StoredConfig getUserConfig()
+ throws IOException, ConfigInvalidException {
+ return userGitConfig;
+ }
+
+ @Override
+ public FileBasedConfig getJGitConfig() {
+ return jgitConfig;
+ }
+
+ @Override
+ public StoredConfig getSystemConfig()
+ throws IOException, ConfigInvalidException {
+ return systemGitConfig;
+ }
+
+ @Override
public String getHostname() {
return "fake.host.example.com";
}
@Override
public long getCurrentTime() {
- return 1250379778668L; // Sat Aug 15 20:12:58 GMT-03:30 2009
+ return now;
+ }
+
+ @Override
+ public MonotonicClock getClock() {
+ return () -> {
+ long t = getCurrentTime();
+ return new ProposedTimestamp() {
+
+ @Override
+ public long read(TimeUnit unit) {
+ return unit.convert(t, TimeUnit.MILLISECONDS);
+ }
+
+ @Override
+ public void blockUntil(Duration maxWait) {
+ // Do not wait.
+ }
+ };
+ };
+ }
+
+ /**
+ * Adjusts the current time in seconds.
+ *
+ * @param secDelta
+ * number of seconds to add to the current time.
+ * @since 4.2
+ */
+ public void tick(int secDelta) {
+ now += secDelta * 1000L;
}
@Override
@@ -151,6 +244,11 @@ public class MockSystemReader extends SystemReader {
}
@Override
+ public ZoneId getTimeZoneId() {
+ return ZoneOffset.ofHoursMinutes(-3, -30);
+ }
+
+ @Override
public Locale getLocale() {
return Locale.US;
}
@@ -170,6 +268,7 @@ public class MockSystemReader extends SystemReader {
* Assign some properties for the currently executing platform
*/
public void setCurrentPlatform() {
+ resetOsNames();
setProperty("os.name", System.getProperty("os.name"));
setProperty("file.separator", System.getProperty("file.separator"));
setProperty("path.separator", System.getProperty("path.separator"));
@@ -180,6 +279,7 @@ public class MockSystemReader extends SystemReader {
* Emulate Windows
*/
public void setWindows() {
+ resetOsNames();
setProperty("os.name", "Windows");
setProperty("file.separator", "\\");
setProperty("path.separator", ";");
@@ -191,10 +291,36 @@ public class MockSystemReader extends SystemReader {
* Emulate Unix
*/
public void setUnix() {
+ resetOsNames();
setProperty("os.name", "*nix"); // Essentially anything but Windows
setProperty("file.separator", "/");
setProperty("path.separator", ":");
setProperty("line.separator", "\n");
setPlatformChecker();
}
+
+ private void resetOsNames() {
+ Field field;
+ try {
+ field = SystemReader.class.getDeclaredField("isWindows");
+ field.setAccessible(true);
+ field.set(null, null);
+ field = SystemReader.class.getDeclaredField("isMacOS");
+ field.setAccessible(true);
+ field.set(null, null);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "MockSystemReader";
+ }
+
+ @Override
+ public FileBasedConfig openJGitConfig(Config parent, FS fs) {
+ return jgitConfig;
+ }
+
}
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/Repeat.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/Repeat.java
new file mode 100644
index 0000000000..4bf2eb59da
--- /dev/null
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/Repeat.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2016, Matthias Sohn <matthias.sohn@sap.com> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.junit;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation enabling to run tests repeatedly
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ java.lang.annotation.ElementType.METHOD })
+public @interface Repeat {
+ /**
+ * Number of repetitions
+ *
+ * @return number of repetitions
+ */
+ public abstract int n();
+
+ /**
+ * Whether to abort execution on first test failure
+ *
+ * @return {@code true} if execution should be aborted on the first failure,
+ * otherwise count failures and continue execution
+ * @since 5.1.9
+ */
+ public boolean abortOnFailure() default true;
+}
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepeatRule.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepeatRule.java
new file mode 100644
index 0000000000..30fffe9d94
--- /dev/null
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepeatRule.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2016, Matthias Sohn <matthias.sohn@sap.com> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.junit;
+
+import java.text.MessageFormat;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * {@link org.junit.rules.TestRule} which enables to run the same JUnit test
+ * repeatedly. Add this rule to the test class
+ *
+ * <pre>
+ * public class MyTest {
+ * &#64;Rule
+ * public RepeatRule repeatRule = new RepeatRule();
+ * ...
+ * }
+ * </pre>
+ *
+ * and annotate the test to be repeated with the
+ * {@code @Repeat(n=<repetitions>)} annotation
+ *
+ * <pre>
+ * &#64;Test
+ * &#64;Repeat(n = 100)
+ * public void test() {
+ * ...
+ * }
+ * </pre>
+ *
+ * then this test will be repeated 100 times. If any test execution fails test
+ * repetition will be stopped.
+ */
+public class RepeatRule implements TestRule {
+
+ private static final Logger LOG = Logger
+ .getLogger(RepeatRule.class.getName());
+
+ /**
+ * Exception thrown if repeated execution of a test annotated with
+ * {@code @Repeat} failed.
+ */
+ public static class RepeatedTestException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructor
+ *
+ * @param message
+ * the error message
+ * @since 5.1.9
+ */
+ public RepeatedTestException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param message
+ * the error message
+ * @param cause
+ * exception causing this exception
+ */
+ public RepeatedTestException(String message, Throwable cause) {
+ super(message, cause);
+ }
+ }
+
+ private static class RepeatStatement extends Statement {
+
+ private final int repetitions;
+
+ private boolean abortOnFailure;
+
+ private final Statement statement;
+
+ private RepeatStatement(int repetitions, boolean abortOnFailure,
+ Statement statement) {
+ this.repetitions = repetitions;
+ this.abortOnFailure = abortOnFailure;
+ this.statement = statement;
+ }
+
+ @Override
+ public void evaluate() throws Throwable {
+ int failures = 0;
+ for (int i = 0; i < repetitions; i++) {
+ try {
+ statement.evaluate();
+ } catch (Throwable e) {
+ failures += 1;
+ RepeatedTestException ex = new RepeatedTestException(
+ MessageFormat.format(
+ "Repeated test failed when run for the {0}. time",
+ Integer.valueOf(i + 1)),
+ e);
+ LOG.log(Level.SEVERE, ex.getMessage(), ex);
+ if (abortOnFailure) {
+ throw ex;
+ }
+ }
+ }
+ if (failures > 0) {
+ RepeatedTestException e = new RepeatedTestException(
+ MessageFormat.format(
+ "Test failed {0} times out of {1} repeated executions",
+ Integer.valueOf(failures),
+ Integer.valueOf(repetitions)));
+ LOG.log(Level.SEVERE, e.getMessage(), e);
+ throw e;
+ }
+ }
+ }
+
+ @Override
+ public Statement apply(Statement statement, Description description) {
+ Statement result = statement;
+ Repeat repeat = description.getAnnotation(Repeat.class);
+ if (repeat != null) {
+ int n = repeat.n();
+ boolean abortOnFailure = repeat.abortOnFailure();
+ result = new RepeatStatement(n, abortOnFailure, statement);
+ }
+ return result;
+ }
+}
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java
index 83148d0009..3a283ce10d 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java
@@ -2,50 +2,18 @@
* Copyright (C) 2009, Google Inc.
* Copyright (C) 2007-2008, Robin Rosenberg <robin.rosenberg@dewire.com>
* Copyright (C) 2006-2007, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2009, Yann Simon <yann.simon.fr@gmail.com>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2009, Yann Simon <yann.simon.fr@gmail.com> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.junit;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertEquals;
import java.io.File;
@@ -55,20 +23,24 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
+import java.nio.file.Path;
+import java.time.Instant;
+import java.util.List;
import java.util.Map;
-import java.util.TreeSet;
+import java.util.concurrent.TimeUnit;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheBuilder;
import org.eclipse.jgit.dircache.DirCacheCheckout;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
+import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
@@ -76,6 +48,7 @@ import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.FileTreeIterator;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.FileUtils;
+import org.junit.After;
import org.junit.Before;
/**
@@ -85,58 +58,136 @@ import org.junit.Before;
* repositories and destroying them when the tests are finished.
*/
public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase {
- protected static void copyFile(final File src, final File dst)
+ /**
+ * Copy a file
+ *
+ * @param src
+ * file to copy
+ * @param dst
+ * destination of the copy
+ * @throws IOException
+ * if an IO error occurred
+ */
+ protected static void copyFile(File src, File dst)
throws IOException {
- final FileInputStream fis = new FileInputStream(src);
- try {
- final FileOutputStream fos = new FileOutputStream(dst);
- try {
- final byte[] buf = new byte[4096];
- int r;
- while ((r = fis.read(buf)) > 0) {
- fos.write(buf, 0, r);
- }
- } finally {
- fos.close();
+ try (FileInputStream fis = new FileInputStream(src);
+ FileOutputStream fos = new FileOutputStream(dst)) {
+ final byte[] buf = new byte[4096];
+ int r;
+ while ((r = fis.read(buf)) > 0) {
+ fos.write(buf, 0, r);
}
- } finally {
- fis.close();
}
}
- protected File writeTrashFile(final String name, final String data)
+ /**
+ * Write a trash file
+ *
+ * @param name
+ * file name
+ * @param data
+ * file content
+ * @return the trash file
+ * @throws IOException
+ * if an IO error occurred
+ */
+ protected File writeTrashFile(String name, String data)
throws IOException {
return JGitTestUtil.writeTrashFile(db, name, data);
}
+ /**
+ * Create a symbolic link
+ *
+ * @param link
+ * the path of the symbolic link to create
+ * @param target
+ * the target of the symbolic link
+ * @return the path to the symbolic link
+ * @throws Exception
+ * if an error occurred
+ * @since 4.2
+ */
+ protected Path writeLink(String link, String target)
+ throws Exception {
+ return JGitTestUtil.writeLink(db, link, target);
+ }
+
+ /**
+ * Write a trash file
+ *
+ * @param subdir
+ * in working tree
+ * @param name
+ * file name
+ * @param data
+ * file content
+ * @return the trash file
+ * @throws IOException
+ * if an IO error occurred
+ */
protected File writeTrashFile(final String subdir, final String name,
final String data)
throws IOException {
return JGitTestUtil.writeTrashFile(db, subdir, name, data);
}
- protected String read(final String name) throws IOException {
+ /**
+ * Read content of a file
+ *
+ * @param name
+ * file name
+ * @return the file's content
+ * @throws IOException
+ * if an IO error occurred
+ */
+ protected String read(String name) throws IOException {
return JGitTestUtil.read(db, name);
}
- protected boolean check(final String name) {
+ /**
+ * Check if file exists
+ *
+ * @param name
+ * file name
+ * @return if the file exists
+ */
+ protected boolean check(String name) {
return JGitTestUtil.check(db, name);
}
- protected void deleteTrashFile(final String name) throws IOException {
+ /**
+ * Delete a trash file
+ *
+ * @param name
+ * file name
+ * @throws IOException
+ * if an IO error occurred
+ */
+ protected void deleteTrashFile(String name) throws IOException {
JGitTestUtil.deleteTrashFile(db, name);
}
- protected static void checkFile(File f, final String checkData)
+ /**
+ * Check content of a file.
+ *
+ * @param f
+ * file
+ * @param checkData
+ * expected content
+ * @throws IOException
+ * if an IO error occurred
+ */
+ protected static void checkFile(File f, String checkData)
throws IOException {
- Reader r = new InputStreamReader(new FileInputStream(f), "ISO-8859-1");
- try {
- char[] data = new char[(int) f.length()];
- if (f.length() != r.read(data))
- throw new IOException("Internal error reading file data from "+f);
- assertEquals(checkData, new String(data));
- } finally {
- r.close();
+ try (Reader r = new InputStreamReader(new FileInputStream(f),
+ UTF_8)) {
+ if (checkData.length() > 0) {
+ char[] data = new char[checkData.length()];
+ assertEquals(data.length, r.read(data));
+ assertEquals(checkData, new String(data));
+ }
+ assertEquals(-1, r.read());
}
}
@@ -154,99 +205,11 @@ public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase {
trash = db.getWorkTree();
}
- public static final int MOD_TIME = 1;
-
- public static final int SMUDGE = 2;
-
- public static final int LENGTH = 4;
-
- public static final int CONTENT_ID = 8;
-
- public static final int CONTENT = 16;
-
- public static final int ASSUME_UNCHANGED = 32;
-
- /**
- * Represent the state of the index in one String. This representation is
- * useful when writing tests which do assertions on the state of the index.
- * By default information about path, mode, stage (if different from 0) is
- * included. A bitmask controls which additional info about
- * modificationTimes, smudge state and length is included.
- * <p>
- * The format of the returned string is described with this BNF:
- *
- * <pre>
- * result = ( "[" path mode stage? time? smudge? length? sha1? content? "]" )* .
- * mode = ", mode:" number .
- * stage = ", stage:" number .
- * time = ", time:t" timestamp-index .
- * smudge = "" | ", smudged" .
- * length = ", length:" number .
- * sha1 = ", sha1:" hex-sha1 .
- * content = ", content:" blob-data .
- * </pre>
- *
- * 'stage' is only presented when the stage is different from 0. All
- * reported time stamps are mapped to strings like "t0", "t1", ... "tn". The
- * smallest reported time-stamp will be called "t0". This allows to write
- * assertions against the string although the concrete value of the time
- * stamps is unknown.
- *
- * @param repo
- * the repository the index state should be determined for
- *
- * @param includedOptions
- * a bitmask constructed out of the constants {@link #MOD_TIME},
- * {@link #SMUDGE}, {@link #LENGTH}, {@link #CONTENT_ID} and
- * {@link #CONTENT} controlling which info is present in the
- * resulting string.
- * @return a string encoding the index state
- * @throws IllegalStateException
- * @throws IOException
- */
- public String indexState(Repository repo, int includedOptions)
- throws IllegalStateException, IOException {
- DirCache dc = repo.readDirCache();
- StringBuilder sb = new StringBuilder();
- TreeSet<Long> timeStamps = null;
-
- // iterate once over the dircache just to collect all time stamps
- if (0 != (includedOptions & MOD_TIME)) {
- timeStamps = new TreeSet<Long>();
- for (int i=0; i<dc.getEntryCount(); ++i)
- timeStamps.add(Long.valueOf(dc.getEntry(i).getLastModified()));
- }
-
- // iterate again, now produce the result string
- for (int i=0; i<dc.getEntryCount(); ++i) {
- DirCacheEntry entry = dc.getEntry(i);
- sb.append("["+entry.getPathString()+", mode:" + entry.getFileMode());
- int stage = entry.getStage();
- if (stage != 0)
- sb.append(", stage:" + stage);
- if (0 != (includedOptions & MOD_TIME)) {
- sb.append(", time:t"+
- timeStamps.headSet(Long.valueOf(entry.getLastModified())).size());
- }
- if (0 != (includedOptions & SMUDGE))
- if (entry.isSmudged())
- sb.append(", smudged");
- if (0 != (includedOptions & LENGTH))
- sb.append(", length:"
- + Integer.toString(entry.getLength()));
- if (0 != (includedOptions & CONTENT_ID))
- sb.append(", sha1:" + ObjectId.toString(entry.getObjectId()));
- if (0 != (includedOptions & CONTENT)) {
- sb.append(", content:"
- + new String(db.open(entry.getObjectId(),
- Constants.OBJ_BLOB).getCachedBytes(), "UTF-8"));
- }
- if (0 != (includedOptions & ASSUME_UNCHANGED))
- sb.append(", assume-unchanged:"
- + Boolean.toString(entry.isAssumeValid()));
- sb.append("]");
- }
- return sb.toString();
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ db.close();
+ super.tearDown();
}
/**
@@ -281,11 +244,11 @@ public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase {
* {@link #CONTENT} controlling which info is present in the
* resulting string.
* @return a string encoding the index state
- * @throws IllegalStateException
* @throws IOException
+ * if an IO error occurred
*/
public String indexState(int includedOptions)
- throws IllegalStateException, IOException {
+ throws IOException {
return indexState(db, includedOptions);
}
@@ -300,10 +263,12 @@ public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase {
* have an index which matches their prepared content.
*
* @param treeItr
- * a {@link FileTreeIterator} which determines which files should
- * go into the new index
+ * a {@link org.eclipse.jgit.treewalk.FileTreeIterator} which
+ * determines which files should go into the new index
* @throws FileNotFoundException
+ * file was not found
* @throws IOException
+ * if an IO error occurred
*/
protected void resetIndex(FileTreeIterator treeItr)
throws FileNotFoundException, IOException {
@@ -316,12 +281,13 @@ public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase {
dce = new DirCacheEntry(treeItr.getEntryPathString());
dce.setFileMode(treeItr.getEntryFileMode());
- dce.setLastModified(treeItr.getEntryLastModified());
+ dce.setLastModified(treeItr.getEntryLastModifiedInstant());
dce.setLength((int) len);
- FileInputStream in = new FileInputStream(
- treeItr.getEntryFile());
- dce.setObjectId(inserter.insert(Constants.OBJ_BLOB, len, in));
- in.close();
+ try (FileInputStream in = new FileInputStream(
+ treeItr.getEntryFile())) {
+ dce.setObjectId(
+ inserter.insert(Constants.OBJ_BLOB, len, in));
+ }
builder.add(dce);
treeItr.next(1);
}
@@ -341,13 +307,13 @@ public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase {
*
* @param l
* the object to lookup
+ * @param lookupTable
+ * a table storing object-name mappings.
* @param nameTemplate
* the name for that object. Can contain "%n" which will be
* replaced by a running number before used as a name. If the
* lookup table already contains the object this parameter will
* be ignored
- * @param lookupTable
- * a table storing object-name mappings.
* @return a name of that object. Is not guaranteed to be unique. Use
* nameTemplates containing "%n" to always have unique names
*/
@@ -363,11 +329,25 @@ public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase {
}
/**
+ * Replaces '\' by '/'
+ *
+ * @param str
+ * the string in which backslashes should be replaced
+ * @return the resulting string with slashes
+ * @since 4.2
+ */
+ public static String slashify(String str) {
+ str = str.replace('\\', '/');
+ return str;
+ }
+
+ /**
* Waits until it is guaranteed that a subsequent file modification has a
* younger modification timestamp than the modification timestamp of the
* given file. This is done by touching a temporary file, reading the
* lastmodified attribute and, if needed, sleeping. After sleeping this loop
- * starts again until the filesystem timer has advanced enough.
+ * starts again until the filesystem timer has advanced enough. The
+ * temporary file will be created as a sibling of lastFile.
*
* @param lastFile
* the file on which we want to wait until the filesystem timer
@@ -376,25 +356,36 @@ public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase {
* @return return the last measured value of the filesystem timer which is
* greater than then the lastmodification time of lastfile.
* @throws InterruptedException
+ * if thread was interrupted
* @throws IOException
+ * if an IO error occurred
+ * @since 5.1.9
*/
- public static long fsTick(File lastFile) throws InterruptedException,
+ public static Instant fsTick(File lastFile)
+ throws InterruptedException,
IOException {
- long sleepTime = 64;
+ File tmp;
FS fs = FS.DETECTED;
- if (lastFile != null && !fs.exists(lastFile))
- throw new FileNotFoundException(lastFile.getPath());
- File tmp = File.createTempFile("FileTreeIteratorWithTimeControl", null);
+ if (lastFile == null) {
+ lastFile = tmp = File
+ .createTempFile("fsTickTmpFile", null);
+ } else {
+ if (!fs.exists(lastFile)) {
+ throw new FileNotFoundException(lastFile.getPath());
+ }
+ tmp = File.createTempFile("fsTickTmpFile", null,
+ lastFile.getParentFile());
+ }
+ long res = FS.getFileStoreAttributes(tmp.toPath())
+ .getFsTimestampResolution().toNanos();
+ long sleepTime = res / 10;
try {
- long startTime = (lastFile == null) ? fs.lastModified(tmp) : fs
- .lastModified(lastFile);
- long actTime = fs.lastModified(tmp);
- while (actTime <= startTime) {
- Thread.sleep(sleepTime);
- sleepTime *= 2;
- FileOutputStream fos = new FileOutputStream(tmp);
- fos.close();
- actTime = fs.lastModified(tmp);
+ Instant startTime = fs.lastModifiedInstant(lastFile);
+ Instant actTime = fs.lastModifiedInstant(tmp);
+ while (actTime.compareTo(startTime) <= 0) {
+ TimeUnit.NANOSECONDS.sleep(sleepTime);
+ FileUtils.touch(tmp.toPath());
+ actTime = fs.lastModifiedInstant(tmp);
}
return actTime;
} finally {
@@ -402,6 +393,16 @@ public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase {
}
}
+ /**
+ * Create a branch
+ *
+ * @param objectId
+ * new value to create the branch on
+ * @param branchName
+ * branch name
+ * @throws IOException
+ * if an IO error occurred
+ */
protected void createBranch(ObjectId objectId, String branchName)
throws IOException {
RefUpdate updateRef = db.updateRef(branchName);
@@ -409,8 +410,27 @@ public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase {
updateRef.update();
}
+ /**
+ * Get all Refs
+ *
+ * @return list of refs
+ * @throws IOException
+ * if an IO error occurred
+ */
+ public List<Ref> getRefs() throws IOException {
+ return db.getRefDatabase().getRefs();
+ }
+
+ /**
+ * Checkout a branch
+ *
+ * @param branchName
+ * branch name
+ * @throws IOException
+ * if an IO error occurred
+ */
protected void checkoutBranch(String branchName)
- throws IllegalStateException, IOException {
+ throws IOException {
try (RevWalk walk = new RevWalk(db)) {
RevCommit head = walk.parseCommit(db.resolve(Constants.HEAD));
RevCommit branch = walk.parseCommit(db.resolve(branchName));
@@ -440,7 +460,9 @@ public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase {
* the contents which should be written into the files
* @return the File object associated to the last written file.
* @throws IOException
+ * if an IO error occurred
* @throws InterruptedException
+ * if thread was interrupted
*/
protected File writeTrashFiles(boolean ensureDistinctTimestamps,
String... contents)
@@ -463,18 +485,20 @@ public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase {
* one.
*
* @param filename
+ * file name
* @param contents
+ * file content
* @param branch
+ * branch name
* @return the created commit
*/
protected RevCommit commitFile(String filename, String contents, String branch) {
- try {
- Git git = new Git(db);
+ try (Git git = new Git(db)) {
Repository repo = git.getRepository();
String originalBranch = repo.getFullBranch();
boolean empty = repo.resolve(Constants.HEAD) == null;
if (!empty) {
- if (repo.getRef(branch) == null)
+ if (repo.findRef(branch) == null)
git.branchCreate().setName(branch).call();
git.checkout().setName(branch).call();
}
@@ -490,31 +514,91 @@ public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase {
git.branchCreate().setName(branch).setStartPoint(commit).call();
return commit;
- } catch (IOException e) {
- throw new RuntimeException(e);
- } catch (GitAPIException e) {
+ } catch (IOException | GitAPIException e) {
throw new RuntimeException(e);
}
}
- protected DirCacheEntry createEntry(final String path, final FileMode mode) {
+ /**
+ * Create <code>DirCacheEntry</code>
+ *
+ * @param path
+ * file path
+ * @param mode
+ * file mode
+ * @return the DirCacheEntry
+ */
+ protected DirCacheEntry createEntry(String path, FileMode mode) {
return createEntry(path, mode, DirCacheEntry.STAGE_0, path);
}
+ /**
+ * Create <code>DirCacheEntry</code>
+ *
+ * @param path
+ * file path
+ * @param mode
+ * file mode
+ * @param content
+ * file content
+ * @return the DirCacheEntry
+ */
protected DirCacheEntry createEntry(final String path, final FileMode mode,
final String content) {
return createEntry(path, mode, DirCacheEntry.STAGE_0, content);
}
+ /**
+ * Create <code>DirCacheEntry</code>
+ *
+ * @param path
+ * file path
+ * @param mode
+ * file mode
+ * @param stage
+ * stage index of the new entry
+ * @param content
+ * file content
+ * @return the DirCacheEntry
+ */
protected DirCacheEntry createEntry(final String path, final FileMode mode,
final int stage, final String content) {
final DirCacheEntry entry = new DirCacheEntry(path, stage);
entry.setFileMode(mode);
- entry.setObjectId(new ObjectInserter.Formatter().idFor(
- Constants.OBJ_BLOB, Constants.encode(content)));
+ try (ObjectInserter.Formatter formatter = new ObjectInserter.Formatter()) {
+ entry.setObjectId(formatter.idFor(
+ Constants.OBJ_BLOB, Constants.encode(content)));
+ }
return entry;
}
+ /**
+ * Create <code>DirCacheEntry</code>
+ *
+ * @param path
+ * file path
+ * @param objectId
+ * of the entry
+ * @return the DirCacheEntry
+ */
+ protected DirCacheEntry createGitLink(String path, AnyObjectId objectId) {
+ final DirCacheEntry entry = new DirCacheEntry(path,
+ DirCacheEntry.STAGE_0);
+ entry.setFileMode(FileMode.GITLINK);
+ entry.setObjectId(objectId);
+ return entry;
+ }
+
+ /**
+ * Assert files are equal
+ *
+ * @param expected
+ * expected file
+ * @param actual
+ * actual file
+ * @throws IOException
+ * if an IO error occurred
+ */
public static void assertEqualsFile(File expected, File actual)
throws IOException {
assertEquals(expected.getCanonicalFile(), actual.getCanonicalFile());
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/SeparateClassloaderTestRunner.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/SeparateClassloaderTestRunner.java
new file mode 100644
index 0000000000..2a482df04a
--- /dev/null
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/SeparateClassloaderTestRunner.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2019 Nail Samatov <sanail@yandex.ru> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.junit;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Paths;
+
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.InitializationError;
+
+/**
+ * This class is used when it's required to load jgit classes in separate
+ * classloader for each test class. It can be needed to isolate static field
+ * initialization between separate tests.
+ *
+ * @since 5.5
+ */
+public class SeparateClassloaderTestRunner extends BlockJUnit4ClassRunner {
+
+ /**
+ * Creates a SeparateClassloaderTestRunner to run {@code klass}.
+ *
+ * @param klass
+ * test class to run.
+ * @throws InitializationError
+ * if the test class is malformed or can't be found.
+ */
+ public SeparateClassloaderTestRunner(Class<?> klass)
+ throws InitializationError {
+ super(loadNewClass(klass));
+ }
+
+ private static Class<?> loadNewClass(Class<?> klass)
+ throws InitializationError {
+ try {
+ String pathSeparator = System.getProperty("path.separator");
+ String[] classPathEntries = System.getProperty("java.class.path")
+ .split(pathSeparator, -1);
+ URL[] urls = new URL[classPathEntries.length];
+ for (int i = 0; i < classPathEntries.length; i++) {
+ urls[i] = Paths.get(classPathEntries[i]).toUri().toURL();
+ }
+ ClassLoader testClassLoader = new URLClassLoader(urls) {
+
+ @Override
+ public Class<?> loadClass(String name)
+ throws ClassNotFoundException {
+ if (name.startsWith("org.eclipse.jgit.")) {
+ return super.findClass(name);
+ }
+
+ return super.loadClass(name);
+ }
+ };
+ return Class.forName(klass.getName(), true, testClassLoader);
+ } catch (ClassNotFoundException | MalformedURLException e) {
+ throw new InitializationError(e);
+ }
+ }
+}
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/StrictWorkMonitor.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/StrictWorkMonitor.java
new file mode 100644
index 0000000000..0168ecea30
--- /dev/null
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/StrictWorkMonitor.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2017 Google Inc. and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.junit;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.jgit.lib.ProgressMonitor;
+
+/**
+ * Strict work monitor
+ */
+public final class StrictWorkMonitor implements ProgressMonitor {
+ private int lastWork, totalWork;
+
+ @Override
+ public void start(int totalTasks) {
+ // empty
+ }
+
+ @Override
+ public void beginTask(String title, int total) {
+ this.totalWork = total;
+ lastWork = 0;
+ }
+
+ @Override
+ public void update(int completed) {
+ lastWork += completed;
+ }
+
+ @Override
+ public void endTask() {
+ assertEquals("Units of work recorded", totalWork, lastWork);
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return false;
+ }
+
+ @Override
+ public void showDuration(boolean enabled) {
+ // not implemented
+ }
+}
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java
index 925a6b0216..c546ae9082 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java
@@ -1,56 +1,27 @@
/*
- * Copyright (C) 2009-2010, Google Inc.
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2009-2010, Google Inc. and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.junit;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
+import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.security.MessageDigest;
+import java.time.Instant;
+import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -60,6 +31,7 @@ import java.util.List;
import java.util.Set;
import java.util.TimeZone;
+import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheBuilder;
@@ -74,8 +46,10 @@ import org.eclipse.jgit.errors.ObjectWritingException;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.internal.storage.file.LockFile;
import org.eclipse.jgit.internal.storage.file.ObjectDirectory;
+import org.eclipse.jgit.internal.storage.file.Pack;
import org.eclipse.jgit.internal.storage.file.PackFile;
import org.eclipse.jgit.internal.storage.file.PackIndex.MutableEntry;
+import org.eclipse.jgit.internal.storage.pack.PackExt;
import org.eclipse.jgit.internal.storage.pack.PackWriter;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Constants;
@@ -99,11 +73,11 @@ import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevTag;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.storage.pack.PackConfig;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
import org.eclipse.jgit.util.ChangeIdUtil;
import org.eclipse.jgit.util.FileUtils;
-import org.eclipse.jgit.util.io.SafeBufferedOutputStream;
/**
* Wrapper to make creating test data easier.
@@ -111,24 +85,23 @@ import org.eclipse.jgit.util.io.SafeBufferedOutputStream;
* @param <R>
* type of Repository the test data is stored on.
*/
-public class TestRepository<R extends Repository> {
- private static final PersonIdent defaultAuthor;
+public class TestRepository<R extends Repository> implements AutoCloseable {
- private static final PersonIdent defaultCommitter;
+ /** Constant <code>AUTHOR="J. Author"</code> */
+ public static final String AUTHOR = "J. Author";
- static {
- final MockSystemReader m = new MockSystemReader();
- final long now = m.getCurrentTime();
- final int tz = m.getTimezone(now);
+ /** Constant <code>AUTHOR_EMAIL="jauthor@example.com"</code> */
+ public static final String AUTHOR_EMAIL = "jauthor@example.com";
- final String an = "J. Author";
- final String ae = "jauthor@example.com";
- defaultAuthor = new PersonIdent(an, ae, now, tz);
+ /** Constant <code>COMMITTER="J. Committer"</code> */
+ public static final String COMMITTER = "J. Committer";
- final String cn = "J. Committer";
- final String ce = "jcommitter@example.com";
- defaultCommitter = new PersonIdent(cn, ce, now, tz);
- }
+ /** Constant <code>COMMITTER_EMAIL="jcommitter@example.com"</code> */
+ public static final String COMMITTER_EMAIL = "jcommitter@example.com";
+
+ private final PersonIdent defaultAuthor;
+
+ private final PersonIdent defaultCommitter;
private final R db;
@@ -138,7 +111,7 @@ public class TestRepository<R extends Repository> {
private final ObjectInserter inserter;
- private long now;
+ private final MockSystemReader mockSystemReader;
/**
* Wrap a repository with test building tools.
@@ -146,9 +119,10 @@ public class TestRepository<R extends Repository> {
* @param db
* the test repository to write into.
* @throws IOException
+ * if an IO error occurred
*/
public TestRepository(R db) throws IOException {
- this(db, new RevWalk(db));
+ this(db, new RevWalk(db), new MockSystemReader());
}
/**
@@ -159,41 +133,110 @@ public class TestRepository<R extends Repository> {
* @param rw
* the RevObject pool to use for object lookup.
* @throws IOException
+ * if an IO error occurred
*/
public TestRepository(R db, RevWalk rw) throws IOException {
+ this(db, rw, new MockSystemReader());
+ }
+
+ /**
+ * Wrap a repository with test building tools.
+ *
+ * @param db
+ * the test repository to write into.
+ * @param rw
+ * the RevObject pool to use for object lookup.
+ * @param reader
+ * the MockSystemReader to use for clock and other system
+ * operations.
+ * @throws IOException
+ * if an IO error occurred
+ * @since 4.2
+ */
+ public TestRepository(R db, RevWalk rw, MockSystemReader reader)
+ throws IOException {
this.db = db;
this.git = Git.wrap(db);
this.pool = rw;
this.inserter = db.newObjectInserter();
- this.now = 1236977987000L;
+ this.mockSystemReader = reader;
+ Instant now = mockSystemReader.now();
+ ZoneId tz = mockSystemReader.getTimeZoneAt(now);
+ defaultAuthor = new PersonIdent(AUTHOR, AUTHOR_EMAIL, now, tz);
+ defaultCommitter = new PersonIdent(COMMITTER, COMMITTER_EMAIL, now, tz);
}
- /** @return the repository this helper class operates against. */
+ /**
+ * Get repository
+ *
+ * @return the repository this helper class operates against.
+ */
public R getRepository() {
return db;
}
- /** @return get the RevWalk pool all objects are allocated through. */
+ /**
+ * Get RevWalk
+ *
+ * @return get the RevWalk pool all objects are allocated through.
+ */
public RevWalk getRevWalk() {
return pool;
}
/**
+ * Return Git API wrapper
+ *
* @return an API wrapper for the underlying repository. This wrapper does
- * not allocate any new resources and need not be closed (but closing
- * it is harmless). */
+ * not allocate any new resources and need not be closed (but
+ * closing it is harmless).
+ */
public Git git() {
return git;
}
- /** @return current time adjusted by {@link #tick(int)}. */
- public Date getClock() {
- return new Date(now);
+ /**
+ * Get date
+ *
+ * @return current date.
+ * @since 4.2
+ * @deprecated Use {@link #getInstant()} instead.
+ */
+ @Deprecated(since = "7.2")
+ public Date getDate() {
+ return new Date(mockSystemReader.getCurrentTime());
+ }
+
+ /**
+ * Get instant
+ *
+ * @return current instant.
+ * @since 6.8
+ */
+ public Instant getInstant() {
+ return mockSystemReader.now();
}
- /** @return timezone used for default identities. */
+ /**
+ * Get timezone
+ *
+ * @return timezone used for default identities.
+ * @deprecated Use {@link #getTimeZoneId()} instead.
+ */
+ @Deprecated(since = "7.2")
public TimeZone getTimeZone() {
- return defaultCommitter.getTimeZone();
+ return mockSystemReader.getTimeZone();
+ }
+
+
+ /**
+ * Get timezone
+ *
+ * @return timezone used for default identities.
+ * @since 7.2
+ */
+ public ZoneId getTimeZoneId() {
+ return mockSystemReader.getTimeZoneId();
}
/**
@@ -202,19 +245,19 @@ public class TestRepository<R extends Repository> {
* @param secDelta
* number of seconds to add to the current time.
*/
- public void tick(final int secDelta) {
- now += secDelta * 1000L;
+ public void tick(int secDelta) {
+ mockSystemReader.tick(secDelta);
}
/**
- * Set the author and committer using {@link #getClock()}.
+ * Set the author and committer using {@link #getInstant()}.
*
* @param c
* the commit builder to store.
*/
public void setAuthorAndCommitter(org.eclipse.jgit.lib.CommitBuilder c) {
- c.setAuthor(new PersonIdent(defaultAuthor, new Date(now)));
- c.setCommitter(new PersonIdent(defaultCommitter, new Date(now)));
+ c.setAuthor(new PersonIdent(defaultAuthor, getInstant()));
+ c.setCommitter(new PersonIdent(defaultCommitter, getInstant()));
}
/**
@@ -224,9 +267,10 @@ public class TestRepository<R extends Repository> {
* file content, will be UTF-8 encoded.
* @return reference to the blob.
* @throws Exception
+ * if an error occurred
*/
- public RevBlob blob(final String content) throws Exception {
- return blob(content.getBytes("UTF-8"));
+ public RevBlob blob(String content) throws Exception {
+ return blob(content.getBytes(UTF_8));
}
/**
@@ -234,16 +278,17 @@ public class TestRepository<R extends Repository> {
*
* @param content
* binary file content.
- * @return reference to the blob.
+ * @return the new, fully parsed blob.
* @throws Exception
+ * if an error occurred
*/
- public RevBlob blob(final byte[] content) throws Exception {
+ public RevBlob blob(byte[] content) throws Exception {
ObjectId id;
try (ObjectInserter ins = inserter) {
id = ins.insert(Constants.OBJ_BLOB, content);
ins.flush();
}
- return pool.lookupBlob(id);
+ return (RevBlob) pool.parseAny(id);
}
/**
@@ -255,8 +300,9 @@ public class TestRepository<R extends Repository> {
* a blob, previously constructed in the repository.
* @return the entry.
* @throws Exception
+ * if an error occurred
*/
- public DirCacheEntry file(final String path, final RevBlob blob)
+ public DirCacheEntry file(String path, RevBlob blob)
throws Exception {
final DirCacheEntry e = new DirCacheEntry(path);
e.setFileMode(FileMode.REGULAR_FILE);
@@ -265,26 +311,47 @@ public class TestRepository<R extends Repository> {
}
/**
+ * Construct a symlink mode tree entry.
+ *
+ * @param path
+ * path of the symlink.
+ * @param blob
+ * a blob, previously constructed in the repository.
+ * @return the entry.
+ * @throws Exception
+ * if an error occurred
+ * @since 6.3
+ */
+ public DirCacheEntry link(String path, RevBlob blob) throws Exception {
+ DirCacheEntry e = new DirCacheEntry(path);
+ e.setFileMode(FileMode.SYMLINK);
+ e.setObjectId(blob);
+ return e;
+ }
+
+ /**
* Construct a tree from a specific listing of file entries.
*
* @param entries
* the files to include in the tree. The collection does not need
* to be sorted properly and may be empty.
- * @return reference to the tree specified by the entry list.
+ * @return the new, fully parsed tree specified by the entry list.
* @throws Exception
+ * if an error occurred
*/
- public RevTree tree(final DirCacheEntry... entries) throws Exception {
+ public RevTree tree(DirCacheEntry... entries) throws Exception {
final DirCache dc = DirCache.newInCore();
final DirCacheBuilder b = dc.builder();
- for (final DirCacheEntry e : entries)
+ for (DirCacheEntry e : entries) {
b.add(e);
+ }
b.finish();
ObjectId root;
try (ObjectInserter ins = inserter) {
root = dc.writeTree(ins);
ins.flush();
}
- return pool.lookupTree(root);
+ return pool.parseTree(root);
}
/**
@@ -296,8 +363,9 @@ public class TestRepository<R extends Repository> {
* the path to find the entry of.
* @return the parsed object entry at this path, never null.
* @throws Exception
+ * if an error occurred
*/
- public RevObject get(final RevTree tree, final String path)
+ public RevObject get(RevTree tree, String path)
throws Exception {
try (TreeWalk tw = new TreeWalk(pool.getObjectReader())) {
tw.setFilter(PathFilterGroup.createFromStrings(Collections
@@ -318,6 +386,23 @@ public class TestRepository<R extends Repository> {
}
/**
+ * Create a new, unparsed commit.
+ * <p>
+ * See {@link #unparsedCommit(int, RevTree, ObjectId...)}. The tree is the
+ * empty tree (no files or subdirectories).
+ *
+ * @param parents
+ * zero or more IDs of the commit's parents.
+ * @return the ID of the new commit.
+ * @throws Exception
+ * if an error occurred
+ * @since 5.5
+ */
+ public ObjectId unparsedCommit(ObjectId... parents) throws Exception {
+ return unparsedCommit(1, tree(), parents);
+ }
+
+ /**
* Create a new commit.
* <p>
* See {@link #commit(int, RevTree, RevCommit...)}. The tree is the empty
@@ -327,8 +412,9 @@ public class TestRepository<R extends Repository> {
* zero or more parents of the commit.
* @return the new commit.
* @throws Exception
+ * if an error occurred
*/
- public RevCommit commit(final RevCommit... parents) throws Exception {
+ public RevCommit commit(RevCommit... parents) throws Exception {
return commit(1, tree(), parents);
}
@@ -343,8 +429,9 @@ public class TestRepository<R extends Repository> {
* zero or more parents of the commit.
* @return the new commit.
* @throws Exception
+ * if an error occurred
*/
- public RevCommit commit(final RevTree tree, final RevCommit... parents)
+ public RevCommit commit(RevTree tree, RevCommit... parents)
throws Exception {
return commit(1, tree, parents);
}
@@ -361,8 +448,9 @@ public class TestRepository<R extends Repository> {
* zero or more parents of the commit.
* @return the new commit.
* @throws Exception
+ * if an error occurred
*/
- public RevCommit commit(final int secDelta, final RevCommit... parents)
+ public RevCommit commit(int secDelta, RevCommit... parents)
throws Exception {
return commit(secDelta, tree(), parents);
}
@@ -380,11 +468,36 @@ public class TestRepository<R extends Repository> {
* the root tree for the commit.
* @param parents
* zero or more parents of the commit.
- * @return the new commit.
+ * @return the new, fully parsed commit.
* @throws Exception
+ * if an error occurred
*/
public RevCommit commit(final int secDelta, final RevTree tree,
final RevCommit... parents) throws Exception {
+ ObjectId id = unparsedCommit(secDelta, tree, parents);
+ return pool.parseCommit(id);
+ }
+
+ /**
+ * Create a new, unparsed commit.
+ * <p>
+ * The author and committer identities are stored using the current
+ * timestamp, after being incremented by {@code secDelta}. The message body
+ * is empty.
+ *
+ * @param secDelta
+ * number of seconds to advance {@link #tick(int)} by.
+ * @param tree
+ * the root tree for the commit.
+ * @param parents
+ * zero or more IDs of the commit's parents.
+ * @return the ID of the new commit.
+ * @throws Exception
+ * if an error occurred
+ * @since 5.5
+ */
+ public ObjectId unparsedCommit(final int secDelta, final RevTree tree,
+ final ObjectId... parents) throws Exception {
tick(secDelta);
final org.eclipse.jgit.lib.CommitBuilder c;
@@ -392,18 +505,22 @@ public class TestRepository<R extends Repository> {
c = new org.eclipse.jgit.lib.CommitBuilder();
c.setTreeId(tree);
c.setParentIds(parents);
- c.setAuthor(new PersonIdent(defaultAuthor, new Date(now)));
- c.setCommitter(new PersonIdent(defaultCommitter, new Date(now)));
+ c.setAuthor(new PersonIdent(defaultAuthor, getInstant()));
+ c.setCommitter(new PersonIdent(defaultCommitter, getInstant()));
c.setMessage("");
ObjectId id;
try (ObjectInserter ins = inserter) {
id = ins.insert(c);
ins.flush();
}
- return pool.lookupCommit(id);
+ return id;
}
- /** @return a new commit builder. */
+ /**
+ * Create commit builder
+ *
+ * @return a new commit builder.
+ */
public CommitBuilder commit() {
return new CommitBuilder();
}
@@ -421,21 +538,22 @@ public class TestRepository<R extends Repository> {
* with {@code refs/tags/}.
* @param dst
* object the tag should be pointed at.
- * @return the annotated tag object.
+ * @return the new, fully parsed annotated tag object.
* @throws Exception
+ * if an error occurred
*/
- public RevTag tag(final String name, final RevObject dst) throws Exception {
+ public RevTag tag(String name, RevObject dst) throws Exception {
final TagBuilder t = new TagBuilder();
t.setObjectId(dst);
t.setTag(name);
- t.setTagger(new PersonIdent(defaultCommitter, new Date(now)));
+ t.setTagger(new PersonIdent(defaultCommitter, getInstant()));
t.setMessage("");
ObjectId id;
try (ObjectInserter ins = inserter) {
id = ins.insert(t);
ins.flush();
}
- return (RevTag) pool.lookupAny(id, Constants.OBJ_TAG);
+ return pool.parseTag(id);
}
/**
@@ -451,6 +569,7 @@ public class TestRepository<R extends Repository> {
* the target object.
* @return the target object.
* @throws Exception
+ * if an error occurred
*/
public RevCommit update(String ref, CommitBuilder to) throws Exception {
return update(ref, to.create());
@@ -461,16 +580,17 @@ public class TestRepository<R extends Repository> {
*
* @param ref
* the name of the reference to amend, which must already exist.
- * If {@code ref} does not start with {@code refs/} and is not the
- * magic names {@code HEAD} {@code FETCH_HEAD} or {@code
- * MERGE_HEAD}, then {@code refs/heads/} will be prefixed in front
- * of the given name, thereby assuming it is a branch.
+ * If {@code ref} does not start with {@code refs/} and is not
+ * the magic names {@code HEAD} {@code FETCH_HEAD} or {@code
+ * MERGE_HEAD}, then {@code refs/heads/} will be prefixed in
+ * front of the given name, thereby assuming it is a branch.
* @return commit builder that amends the branch on commit.
* @throws Exception
+ * if an error occurred
*/
public CommitBuilder amendRef(String ref) throws Exception {
String name = normalizeRef(ref);
- Ref r = db.getRef(name);
+ Ref r = db.exactRef(name);
if (r == null)
throw new IOException("Not a ref: " + ref);
return amend(pool.parseCommit(r.getObjectId()), branch(name).commit());
@@ -483,6 +603,7 @@ public class TestRepository<R extends Repository> {
* the id of the commit to amend.
* @return commit builder.
* @throws Exception
+ * if an error occurred
*/
public CommitBuilder amend(AnyObjectId id) throws Exception {
return amend(pool.parseCommit(id), commit());
@@ -537,6 +658,7 @@ public class TestRepository<R extends Repository> {
* the target object.
* @return the target object.
* @throws Exception
+ * if an error occurred
*/
public <T extends AnyObjectId> T update(String ref, T obj) throws Exception {
ref = normalizeRef(ref);
@@ -555,6 +677,33 @@ public class TestRepository<R extends Repository> {
}
}
+ /**
+ * Delete a reference.
+ *
+ * @param ref
+ * the name of the reference to delete. This is normalized in the
+ * same way as {@link #update(String, AnyObjectId)}.
+ * @throws Exception
+ * if an error occurred
+ * @since 4.4
+ */
+ public void delete(String ref) throws Exception {
+ ref = normalizeRef(ref);
+ RefUpdate u = db.updateRef(ref);
+ u.setForceUpdate(true);
+ switch (u.delete()) {
+ case FAST_FORWARD:
+ case FORCED:
+ case NEW:
+ case NO_CHANGE:
+ updateServerInfo();
+ return;
+
+ default:
+ throw new IOException("Cannot delete " + ref + " " + u.getResult());
+ }
+ }
+
private static String normalizeRef(String ref) {
if (Constants.HEAD.equals(ref)) {
// nothing
@@ -571,10 +720,11 @@ public class TestRepository<R extends Repository> {
/**
* Soft-reset HEAD to a detached state.
- * <p>
+ *
* @param id
* ID of detached head.
* @throws Exception
+ * if an error occurred
* @see #reset(String)
*/
public void reset(AnyObjectId id) throws Exception {
@@ -596,13 +746,14 @@ public class TestRepository<R extends Repository> {
/**
* Soft-reset HEAD to a different commit.
* <p>
- * This is equivalent to {@code git reset --soft} in that it modifies HEAD but
- * not the index or the working tree of a non-bare repository.
+ * This is equivalent to {@code git reset --soft} in that it modifies HEAD
+ * but not the index or the working tree of a non-bare repository.
*
* @param name
- * revision string; either an existing ref name, or something that
- * can be parsed to an object ID.
+ * revision string; either an existing ref name, or something
+ * that can be parsed to an object ID.
* @throws Exception
+ * if an error occurred
*/
public void reset(String name) throws Exception {
RefUpdate.Result result;
@@ -633,9 +784,10 @@ public class TestRepository<R extends Repository> {
*
* @param id
* commit-ish to cherry-pick.
- * @return newly created commit, or null if no work was done due to the
- * resulting tree being identical.
+ * @return the new, fully parsed commit, or null if no work was done due to
+ * the resulting tree being identical.
* @throws Exception
+ * if an error occurred
*/
public RevCommit cherryPick(AnyObjectId id) throws Exception {
RevCommit commit = pool.parseCommit(id);
@@ -647,7 +799,7 @@ public class TestRepository<R extends Repository> {
RevCommit parent = commit.getParent(0);
pool.parseHeaders(parent);
- Ref headRef = db.getRef(Constants.HEAD);
+ Ref headRef = db.exactRef(Constants.HEAD);
if (headRef == null)
throw new IOException("Missing HEAD");
RevCommit head = pool.parseCommit(headRef.getObjectId());
@@ -655,7 +807,7 @@ public class TestRepository<R extends Repository> {
ThreeWayMerger merger = MergeStrategy.RECURSIVE.newMerger(db, true);
merger.setBase(parent.getTree());
if (merger.merge(head, commit)) {
- if (AnyObjectId.equals(head.getTree(), merger.getResultTreeId()))
+ if (AnyObjectId.isEqual(head.getTree(), merger.getResultTreeId()))
return null;
tick(1);
org.eclipse.jgit.lib.CommitBuilder b =
@@ -663,7 +815,7 @@ public class TestRepository<R extends Repository> {
b.setParentId(head);
b.setTreeId(merger.getResultTreeId());
b.setAuthor(commit.getAuthorIdent());
- b.setCommitter(new PersonIdent(defaultCommitter, new Date(now)));
+ b.setCommitter(new PersonIdent(defaultCommitter, getInstant()));
b.setMessage(commit.getFullMessage());
ObjectId result;
try (ObjectInserter ins = inserter) {
@@ -672,22 +824,22 @@ public class TestRepository<R extends Repository> {
}
update(Constants.HEAD, result);
return pool.parseCommit(result);
- } else {
- throw new IOException("Merge conflict");
}
+ throw new IOException("Merge conflict");
}
/**
* Update the dumb client server info files.
*
* @throws Exception
+ * if an error occurred
*/
public void updateServerInfo() throws Exception {
if (db instanceof FileRepository) {
final FileRepository fr = (FileRepository) db;
- RefWriter rw = new RefWriter(fr.getAllRefs().values()) {
+ RefWriter rw = new RefWriter(fr.getRefDatabase().getRefs()) {
@Override
- protected void writeFile(final String name, final byte[] bin)
+ protected void writeFile(String name, byte[] bin)
throws IOException {
File path = new File(fr.getDirectory(), name);
TestRepository.this.writeFile(path, bin);
@@ -697,7 +849,7 @@ public class TestRepository<R extends Repository> {
rw.writeInfoRefs();
final StringBuilder w = new StringBuilder();
- for (PackFile p : fr.getObjectDatabase().getPacks()) {
+ for (Pack p : fr.getObjectDatabase().getPacks()) {
w.append("P ");
w.append(p.getPackFile().getName());
w.append('\n');
@@ -711,14 +863,16 @@ public class TestRepository<R extends Repository> {
* Ensure the body of the given object has been parsed.
*
* @param <T>
- * type of object, e.g. {@link RevTag} or {@link RevCommit}.
+ * type of object, e.g. {@link org.eclipse.jgit.revwalk.RevTag}
+ * or {@link org.eclipse.jgit.revwalk.RevCommit}.
* @param object
* reference to the (possibly unparsed) object to force body
* parsing of.
* @return {@code object}
* @throws Exception
+ * if an error occurred
*/
- public <T extends RevObject> T parseBody(final T object) throws Exception {
+ public <T extends RevObject> T parseBody(T object) throws Exception {
pool.parseBody(object);
return object;
}
@@ -752,6 +906,7 @@ public class TestRepository<R extends Repository> {
* the object to tag
* @return the tagged object
* @throws Exception
+ * if an error occurred
*/
public ObjectId lightweightTag(String name, ObjectId obj) throws Exception {
if (!name.startsWith(Constants.R_TAGS))
@@ -769,8 +924,11 @@ public class TestRepository<R extends Repository> {
* the tips to start checking from; if not supplied the refs of
* the repository are used instead.
* @throws MissingObjectException
+ * if object is missing
* @throws IncorrectObjectTypeException
+ * if object has unexpected type
* @throws IOException
+ * if an IO error occurred
*/
public void fsck(RevObject... tips) throws MissingObjectException,
IncorrectObjectTypeException, IOException {
@@ -779,7 +937,7 @@ public class TestRepository<R extends Repository> {
for (RevObject o : tips)
ow.markStart(ow.parseAny(o));
} else {
- for (Ref r : db.getAllRefs().values())
+ for (Ref r : db.getRefDatabase().getRefs())
ow.markStart(ow.parseAny(r.getObjectId()));
}
@@ -790,7 +948,7 @@ public class TestRepository<R extends Repository> {
break;
final byte[] bin = db.open(o, o.getType()).getCachedBytes();
- oc.checkCommit(bin);
+ oc.checkCommit(o, bin);
assertHash(o, bin);
}
@@ -800,7 +958,7 @@ public class TestRepository<R extends Repository> {
break;
final byte[] bin = db.open(o, o.getType()).getCachedBytes();
- oc.check(o.getType(), bin);
+ oc.check(o, o.getType(), bin);
assertHash(o, bin);
}
}
@@ -823,34 +981,44 @@ public class TestRepository<R extends Repository> {
* not removed.
*
* @throws Exception
+ * if an error occurred
*/
public void packAndPrune() throws Exception {
if (db.getObjectDatabase() instanceof ObjectDirectory) {
ObjectDirectory odb = (ObjectDirectory) db.getObjectDatabase();
NullProgressMonitor m = NullProgressMonitor.INSTANCE;
- final File pack, idx;
+ PackFile pack;
try (PackWriter pw = new PackWriter(db)) {
- Set<ObjectId> all = new HashSet<ObjectId>();
- for (Ref r : db.getAllRefs().values())
+ Set<ObjectId> all = new HashSet<>();
+ for (Ref r : db.getRefDatabase().getRefs())
all.add(r.getObjectId());
- pw.preparePack(m, all, Collections.<ObjectId> emptySet());
+ pw.preparePack(m, all, PackWriter.NONE);
- final ObjectId name = pw.computeName();
-
- pack = nameFor(odb, name, ".pack");
+ pack = new PackFile(odb.getPackDirectory(), pw.computeName(),
+ PackExt.PACK);
try (OutputStream out =
- new SafeBufferedOutputStream(new FileOutputStream(pack))) {
+ new BufferedOutputStream(new FileOutputStream(pack))) {
pw.writePack(m, m, out);
}
pack.setReadOnly();
- idx = nameFor(odb, name, ".idx");
+ PackFile idx = pack.create(PackExt.INDEX);
try (OutputStream out =
- new SafeBufferedOutputStream(new FileOutputStream(idx))) {
+ new BufferedOutputStream(new FileOutputStream(idx))) {
pw.writeIndex(out);
}
idx.setReadOnly();
+
+ PackConfig pc = new PackConfig(db);
+ if (pc.getMinBytesForObjSizeIndex() >= 0) {
+ PackFile oidx = pack.create(PackExt.OBJECT_SIZE_INDEX);
+ try (OutputStream out = new BufferedOutputStream(
+ new FileOutputStream(oidx))) {
+ pw.writeObjectSizeIndex(out);
+ }
+ oidx.setReadOnly();
+ }
}
odb.openPack(pack);
@@ -859,27 +1027,40 @@ public class TestRepository<R extends Repository> {
}
}
- private static void prunePacked(ObjectDirectory odb) throws IOException {
- for (PackFile p : odb.getPacks()) {
- for (MutableEntry e : p)
- FileUtils.delete(odb.fileFor(e.toObjectId()));
+ /**
+ * Closes the underlying {@link Repository} object and any other internal
+ * resources.
+ * <p>
+ * {@link AutoCloseable} resources that may escape this object, such as
+ * those returned by the {@link #git} and {@link #getRevWalk()} methods are
+ * not closed.
+ */
+ @Override
+ public void close() {
+ try {
+ inserter.close();
+ } finally {
+ db.close();
}
}
- private static File nameFor(ObjectDirectory odb, ObjectId name, String t) {
- File packdir = new File(odb.getDirectory(), "pack");
- return new File(packdir, "pack-" + name.name() + t);
+ private static void prunePacked(ObjectDirectory odb) throws IOException {
+ for (Pack p : odb.getPacks()) {
+ for (MutableEntry e : p)
+ FileUtils.delete(odb.fileFor(e.toObjectId()),
+ FileUtils.SKIP_MISSING);
+ }
}
- private void writeFile(final File p, final byte[] bin) throws IOException,
+ private void writeFile(File p, byte[] bin) throws IOException,
ObjectWritingException {
- final LockFile lck = new LockFile(p, db.getFS());
+ final LockFile lck = new LockFile(p);
if (!lck.lock())
throw new ObjectWritingException("Can't write " + p);
try {
lck.write(bin);
} catch (IOException ioe) {
- throw new ObjectWritingException("Can't write " + p);
+ throw new ObjectWritingException("Can't write " + p, ioe);
}
if (!lck.commit())
throw new ObjectWritingException("Can't write " + p);
@@ -889,11 +1070,13 @@ public class TestRepository<R extends Repository> {
public class BranchBuilder {
private final String ref;
- BranchBuilder(final String ref) {
+ BranchBuilder(String ref) {
this.ref = ref;
}
/**
+ * Create commit builder
+ *
* @return construct a new commit builder that updates this branch. If
* the branch already exists, the commit builder will have its
* first parent as the current commit and its tree will be
@@ -912,6 +1095,7 @@ public class TestRepository<R extends Repository> {
* the commit to update to.
* @return {@code to}.
* @throws Exception
+ * if an error occurred
*/
public RevCommit update(CommitBuilder to) throws Exception {
return update(to.create());
@@ -924,10 +1108,22 @@ public class TestRepository<R extends Repository> {
* the commit to update to.
* @return {@code to}.
* @throws Exception
+ * if an error occurred
*/
public RevCommit update(RevCommit to) throws Exception {
return TestRepository.this.update(ref, to);
}
+
+ /**
+ * Delete this branch.
+ *
+ * @throws Exception
+ * if an error occurred
+ * @since 4.4
+ */
+ public void delete() throws Exception {
+ TestRepository.this.delete(ref);
+ }
}
/** Helper to generate a commit. */
@@ -938,7 +1134,7 @@ public class TestRepository<R extends Repository> {
private ObjectId topLevelTree;
- private final List<RevCommit> parents = new ArrayList<RevCommit>(2);
+ private final List<RevCommit> parents = new ArrayList<>(2);
private int tick = 1;
@@ -960,7 +1156,7 @@ public class TestRepository<R extends Repository> {
CommitBuilder(BranchBuilder b) throws Exception {
branch = b;
- Ref ref = db.getRef(branch.ref);
+ Ref ref = db.exactRef(branch.ref);
if (ref != null && ref.getObjectId() != null)
parent(pool.parseCommit(ref.getObjectId()));
}
@@ -976,7 +1172,19 @@ public class TestRepository<R extends Repository> {
parents.add(prior.create());
}
- public CommitBuilder parent(RevCommit p) throws Exception {
+ /**
+ * Set parent commit
+ *
+ * @param p
+ * parent commit, can be {@code null}
+ * @return this commit builder
+ * @throws Exception
+ * if an error occurred
+ */
+ public CommitBuilder parent(@Nullable RevCommit p) throws Exception {
+ if (p == null) {
+ return this;
+ }
if (parents.isEmpty()) {
DirCacheBuilder b = tree.builder();
parseBody(p);
@@ -988,30 +1196,74 @@ public class TestRepository<R extends Repository> {
return this;
}
+ /**
+ * Get parent commits
+ *
+ * @return parent commits
+ */
public List<RevCommit> parents() {
return Collections.unmodifiableList(parents);
}
+ /**
+ * Remove parent commits
+ *
+ * @return this commit builder
+ */
public CommitBuilder noParents() {
parents.clear();
return this;
}
+ /**
+ * Remove files
+ *
+ * @return this commit builder
+ */
public CommitBuilder noFiles() {
tree.clear();
return this;
}
+ /**
+ * Set top level tree
+ *
+ * @param treeId
+ * the top level tree
+ * @return this commit builder
+ */
public CommitBuilder setTopLevelTree(ObjectId treeId) {
topLevelTree = treeId;
return this;
}
+ /**
+ * Add file with given content
+ *
+ * @param path
+ * path of the file
+ * @param content
+ * the file content
+ * @return this commit builder
+ * @throws Exception
+ * if an error occurred
+ */
public CommitBuilder add(String path, String content) throws Exception {
return add(path, blob(content));
}
- public CommitBuilder add(String path, final RevBlob id)
+ /**
+ * Add file with given path and blob
+ *
+ * @param path
+ * path of the file
+ * @param id
+ * blob for this file
+ * @return this commit builder
+ * @throws Exception
+ * if an error occurred
+ */
+ public CommitBuilder add(String path, RevBlob id)
throws Exception {
return edit(new PathEdit(path) {
@Override
@@ -1022,6 +1274,13 @@ public class TestRepository<R extends Repository> {
});
}
+ /**
+ * Edit the index
+ *
+ * @param edit
+ * the index record update
+ * @return this commit builder
+ */
public CommitBuilder edit(PathEdit edit) {
DirCacheEditor e = tree.editor();
e.add(edit);
@@ -1029,6 +1288,13 @@ public class TestRepository<R extends Repository> {
return this;
}
+ /**
+ * Remove a file
+ *
+ * @param path
+ * path of the file
+ * @return this commit builder
+ */
public CommitBuilder rm(String path) {
DirCacheEditor e = tree.editor();
e.add(new DeletePath(path));
@@ -1037,49 +1303,111 @@ public class TestRepository<R extends Repository> {
return this;
}
+ /**
+ * Set commit message
+ *
+ * @param m
+ * the message
+ * @return this commit builder
+ */
public CommitBuilder message(String m) {
message = m;
return this;
}
+ /**
+ * Get the commit message
+ *
+ * @return the commit message
+ */
public String message() {
return message;
}
+ /**
+ * Tick the clock
+ *
+ * @param secs
+ * number of seconds
+ * @return this commit builder
+ */
public CommitBuilder tick(int secs) {
tick = secs;
return this;
}
+ /**
+ * Set author and committer identity
+ *
+ * @param ident
+ * identity to set
+ * @return this commit builder
+ */
public CommitBuilder ident(PersonIdent ident) {
author = ident;
committer = ident;
return this;
}
+ /**
+ * Set the author identity
+ *
+ * @param a
+ * the author's identity
+ * @return this commit builder
+ */
public CommitBuilder author(PersonIdent a) {
author = a;
return this;
}
+ /**
+ * Get the author identity
+ *
+ * @return the author identity
+ */
public PersonIdent author() {
return author;
}
+ /**
+ * Set the committer identity
+ *
+ * @param c
+ * the committer identity
+ * @return this commit builder
+ */
public CommitBuilder committer(PersonIdent c) {
committer = c;
return this;
}
+ /**
+ * Get the committer identity
+ *
+ * @return the committer identity
+ */
public PersonIdent committer() {
return committer;
}
+ /**
+ * Insert changeId
+ *
+ * @return this commit builder
+ */
public CommitBuilder insertChangeId() {
changeId = "";
return this;
}
+ /**
+ * Insert given changeId
+ *
+ * @param c
+ * changeId
+ * @return this commit builder
+ */
public CommitBuilder insertChangeId(String c) {
// Validate, but store as a string so we can use "" as a sentinel.
ObjectId.fromString(c);
@@ -1087,6 +1415,13 @@ public class TestRepository<R extends Repository> {
return this;
}
+ /**
+ * Create the commit
+ *
+ * @return the new commit
+ * @throws Exception
+ * if creation failed
+ */
public RevCommit create() throws Exception {
if (self == null) {
TestRepository.this.tick(tick);
@@ -1100,7 +1435,7 @@ public class TestRepository<R extends Repository> {
c.setAuthor(author);
if (committer != null) {
if (updateCommitterTime)
- committer = new PersonIdent(committer, new Date(now));
+ committer = new PersonIdent(committer, getInstant());
c.setCommitter(committer);
}
@@ -1115,7 +1450,7 @@ public class TestRepository<R extends Repository> {
commitId = ins.insert(c);
ins.flush();
}
- self = pool.lookupCommit(commitId);
+ self = pool.parseCommit(commitId);
if (branch != null)
branch.update(self);
@@ -1123,8 +1458,7 @@ public class TestRepository<R extends Repository> {
return self;
}
- private void insertChangeId(org.eclipse.jgit.lib.CommitBuilder c)
- throws IOException {
+ private void insertChangeId(org.eclipse.jgit.lib.CommitBuilder c) {
if (changeId == null)
return;
int idx = ChangeIdUtil.indexOfChangeId(message, "\n");
@@ -1136,7 +1470,7 @@ public class TestRepository<R extends Repository> {
firstParentId = parents.get(0);
ObjectId cid;
- if (changeId.equals(""))
+ if (changeId.isEmpty())
cid = ChangeIdUtil.computeChangeId(c.getTreeId(), firstParentId,
c.getAuthor(), c.getCommitter(), message);
else
@@ -1148,6 +1482,13 @@ public class TestRepository<R extends Repository> {
+ cid.getName() + "\n"); //$NON-NLS-1$
}
+ /**
+ * Create child commit builder
+ *
+ * @return child commit builder
+ * @throws Exception
+ * if an error occurred
+ */
public CommitBuilder child() throws Exception {
return new CommitBuilder(this);
}
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRng.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRng.java
index 93facc3777..e7fe48845b 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRng.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRng.java
@@ -1,49 +1,18 @@
/*
- * Copyright (C) 2008-2010, Google Inc.
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008-2010, Google Inc. and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.junit;
-/** Toy RNG to ensure we get predictable numbers during unit tests. */
+/**
+ * Toy RNG to ensure we get predictable numbers during unit tests.
+ */
public class TestRng {
private int next;
@@ -53,7 +22,7 @@ public class TestRng {
* @param seed
* seed to bootstrap, usually this is the test method name.
*/
- public TestRng(final String seed) {
+ public TestRng(String seed) {
next = 0;
for (int i = 0; i < seed.length(); i++)
next = next * 11 + seed.charAt(i);
@@ -66,7 +35,7 @@ public class TestRng {
* number of random bytes to produce.
* @return array of {@code cnt} randomly generated bytes.
*/
- public byte[] nextBytes(final int cnt) {
+ public byte[] nextBytes(int cnt) {
final byte[] r = new byte[cnt];
for (int i = 0; i < cnt; i++)
r[i] = (byte) nextInt();
@@ -74,6 +43,8 @@ public class TestRng {
}
/**
+ * Next int
+ *
* @return the next random integer.
*/
public int nextInt() {
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/time/MonotonicFakeClock.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/time/MonotonicFakeClock.java
new file mode 100644
index 0000000000..31db6a2c7b
--- /dev/null
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/time/MonotonicFakeClock.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016, Google Inc. and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.junit.time;
+
+import java.time.Duration;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jgit.util.time.MonotonicClock;
+import org.eclipse.jgit.util.time.ProposedTimestamp;
+
+/**
+ * Fake {@link org.eclipse.jgit.util.time.MonotonicClock} for testing code that
+ * uses Clock.
+ *
+ * @since 4.6
+ */
+public class MonotonicFakeClock implements MonotonicClock {
+ private long now = TimeUnit.SECONDS.toMicros(42);
+
+ /**
+ * Advance the time returned by future calls to {@link #propose()}.
+ *
+ * @param add
+ * amount of time to add; must be {@code > 0}.
+ * @param unit
+ * unit of {@code add}.
+ */
+ public void tick(long add, TimeUnit unit) {
+ if (add <= 0) {
+ throw new IllegalArgumentException();
+ }
+ now += unit.toMillis(add);
+ }
+
+ @Override
+ public ProposedTimestamp propose() {
+ long t = now++;
+ return new ProposedTimestamp() {
+ @Override
+ public long read(TimeUnit unit) {
+ return unit.convert(t, TimeUnit.MILLISECONDS);
+ }
+
+ @Override
+ public void blockUntil(Duration maxWait) {
+ // Nothing to do, since fake time does not go backwards.
+ }
+ };
+ }
+}
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/time/TimeUtil.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/time/TimeUtil.java
new file mode 100644
index 0000000000..f93ac57f13
--- /dev/null
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/time/TimeUtil.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2019, Matthias Sohn <matthias.sohn@sap.com> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.junit.time;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.FileTime;
+import java.time.Instant;
+
+import org.eclipse.jgit.util.FS;
+
+/**
+ * Utility methods for handling timestamps
+ *
+ * @since 5.1.9
+ */
+public class TimeUtil {
+ /**
+ * Set the lastModified time of a given file by adding a given offset to the
+ * current lastModified time
+ *
+ * @param path
+ * path of a file to set last modified
+ * @param offsetMillis
+ * offset in milliseconds, if negative the new lastModified time
+ * is offset before the original lastModified time, otherwise
+ * after the original time
+ * @return the new lastModified time
+ */
+ public static Instant setLastModifiedWithOffset(Path path,
+ long offsetMillis) {
+ Instant mTime = FS.DETECTED.lastModifiedInstant(path)
+ .plusMillis(offsetMillis);
+ try {
+ Files.setLastModifiedTime(path, FileTime.from(mTime));
+ return mTime;
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ /**
+ * Set the lastModified time of file a to the one from file b
+ *
+ * @param a
+ * file to set lastModified time
+ * @param b
+ * file to read lastModified time from
+ */
+ public static void setLastModifiedOf(Path a, Path b) {
+ Instant mTime = FS.DETECTED.lastModifiedInstant(b);
+ try {
+ Files.setLastModifiedTime(a, FileTime.from(mTime));
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+}