@@ -46,14 +46,19 @@ pub fn update_head(
46
46
use git_ref:: transaction:: { PreviousValue , RefEdit } ;
47
47
use git_ref:: Target ;
48
48
use std:: convert:: TryInto ;
49
- let ( head_peeled_id, head_ref) = match remote_refs. iter ( ) . find_map ( |r| match r {
50
- git_protocol:: fetch:: Ref :: Symbolic {
51
- full_ref_name,
52
- target,
53
- object,
54
- } if full_ref_name == "HEAD" => Some ( ( object, Some ( target) ) ) ,
55
- git_protocol:: fetch:: Ref :: Direct { full_ref_name, object } if full_ref_name == "HEAD" => Some ( ( object, None ) ) ,
56
- _ => None ,
49
+ let ( head_peeled_id, head_ref) = match remote_refs. iter ( ) . find_map ( |r| {
50
+ Some ( match r {
51
+ git_protocol:: fetch:: Ref :: Symbolic {
52
+ full_ref_name,
53
+ target,
54
+ object,
55
+ } if full_ref_name == "HEAD" => ( Some ( object) , Some ( target) ) ,
56
+ git_protocol:: fetch:: Ref :: Direct { full_ref_name, object } if full_ref_name == "HEAD" => {
57
+ ( Some ( object) , None )
58
+ }
59
+ git_protocol:: fetch:: Ref :: Unborn { target } => ( None , Some ( target) ) ,
60
+ _ => return None ,
61
+ } )
57
62
} ) {
58
63
Some ( t) => t,
59
64
None => return Ok ( ( ) ) ,
@@ -82,39 +87,46 @@ pub fn update_head(
82
87
} ) ,
83
88
) )
84
89
. prepare (
85
- [
86
- RefEdit {
87
- change : git_ref:: transaction:: Change :: Update {
88
- log : reflog_message ( ) ,
89
- expected : PreviousValue :: Any ,
90
- new : Target :: Peeled ( head_peeled_id. to_owned ( ) ) ,
91
- } ,
92
- name : referent. clone ( ) ,
93
- deref : false ,
94
- } ,
95
- RefEdit {
90
+ {
91
+ let mut edits = vec ! [ RefEdit {
96
92
change: git_ref:: transaction:: Change :: Update {
97
93
log: reflog_message( ) ,
98
94
expected: PreviousValue :: Any ,
99
- new : Target :: Symbolic ( referent) ,
95
+ new: Target :: Symbolic ( referent. clone ( ) ) ,
100
96
} ,
101
97
name: head. clone( ) ,
102
98
deref: false ,
103
- } ,
104
- ] ,
99
+ } ] ;
100
+ if let Some ( head_peeled_id) = head_peeled_id {
101
+ edits. push ( RefEdit {
102
+ change : git_ref:: transaction:: Change :: Update {
103
+ log : reflog_message ( ) ,
104
+ expected : PreviousValue :: Any ,
105
+ new : Target :: Peeled ( head_peeled_id. to_owned ( ) ) ,
106
+ } ,
107
+ name : referent,
108
+ deref : false ,
109
+ } ) ;
110
+ } ;
111
+ edits
112
+ } ,
105
113
git_lock:: acquire:: Fail :: Immediately ,
106
114
git_lock:: acquire:: Fail :: Immediately ,
107
115
)
108
116
. map_err ( crate :: reference:: edit:: Error :: from) ?
109
117
. commit ( repo. committer_or_default ( ) )
110
118
. map_err ( crate :: reference:: edit:: Error :: from) ?;
119
+
111
120
let mut log = reflog_message ( ) ;
112
121
log. mode = RefLog :: Only ;
113
122
repo. edit_reference ( RefEdit {
114
123
change : git_ref:: transaction:: Change :: Update {
115
124
log,
116
125
expected : PreviousValue :: Any ,
117
- new : Target :: Peeled ( head_peeled_id. to_owned ( ) ) ,
126
+ new : Target :: Peeled ( match head_peeled_id {
127
+ Some ( id) => id. to_owned ( ) ,
128
+ None => git_hash:: ObjectId :: null ( repo. object_hash ( ) ) ,
129
+ } ) ,
118
130
} ,
119
131
name : head,
120
132
deref : false ,
@@ -125,7 +137,11 @@ pub fn update_head(
125
137
change : git_ref:: transaction:: Change :: Update {
126
138
log : reflog_message ( ) ,
127
139
expected : PreviousValue :: Any ,
128
- new : Target :: Peeled ( head_peeled_id. to_owned ( ) ) ,
140
+ new : Target :: Peeled (
141
+ head_peeled_id
142
+ . expect ( "detached heads always point to something" )
143
+ . to_owned ( ) ,
144
+ ) ,
129
145
} ,
130
146
name : head,
131
147
deref : false ,
0 commit comments